I have a WPF application with a WCF service layer and a SQL database.
I now want to restrict elements of the application so that certain functions are only available to those users with a particular role. For example, you will only be able to navigate to the settings screen if you are an administrator.
I would like a user to be a member of 1 or more authorisation groups and each authorisation group to have 1 or more roles associated.
A long time ago I used AzMan (Authorisation Manager) to do a similar thing. Does anyone think that there are better approaches? Is AzMan "old news"? Alternatives?
Thanks.
I don't think azman is old news, we are still using it....
Authorization and Entitlement solution on .Net like earlier in AzMan
Azman will do what you are asking....
Well I'd do (actually I already did) the following.
I guess you got your business rules (users, groups) defined in your SQL Database. So you could simply do the Authorisation at the UserControl level. Give each of your UserControls the property hasAuthorization and bind it to the isEnabled property. You can also bind it to the Visibility attribute.
Related
I am in the process of creating a web application that allows users to add, edit and share content and need some help understanding how to set permissions for the content. Here is the setup:
There are multiple users.
Each user can add content (an object created from a class called Project)
For each project, the user who added it can set the permissions that restrict what other users can do. To keep it simple, let's say there are two permissions: view and edit.
Item 1 is very straight forward and ASP.NET provides user login and identities. 2 is also simple. What about 3? What is the best way to store and enforce these permissions? One way to do this with code is to have a list in the project class that stores user IDs and the associated permissions.
But are there built in features in ASP.NET to facilitate 3? I am familiar with roles, but I don't think that they would work because each project might give users different permissions. I have also been reading about policies, but I don't understand it well enough yet to figure out if I could use it to handle the permissions.
Please let me know if existing ASP.NET features can be used to manage the permissions. If not, is the approach that involves storing the User IDs and permissions the way to go or is there a better (safer) way to do it?
I'm working on a project for an events site. I want to create it so that users can create an event and they become the admin for only that event, and they can authorise others as fellow admins (FB style), meanwhile they are only a user for. Is it possible to use the existing roles tools built into .NET to do this?
Thanks
The comments provided are pretty useful (create your own table for it\creating roles on the fly). In short, the functionality you are looking for is not currently available in the existing Universal Role Provider packaged with .NET. However, the URP is intended to only be a starting framework for you to work with\edit as you see fit. I would use a combination of these 2 suggestions, using the built in role provider tables to generate roles on the fly, and use a custom table to manage that hierarchy.
Hope this helps, and welcome to Stack Overflow!
I want to go one step further than simple roles based authorisation (Admin, User, Super User etc)
and instead do Activity based authorisation .
My thinking was to assign activities to logged in users which related to whether or not they could perform a action.
For example
CreateUser
ReadUser
UpdateUser
DeleteUser
I would create pages that relate to the above activities
i.e
CreateUser.aspx
on each page i would do a check to see if the authenticated user does in fact have rights to access the activity.
i would do this by making use of Roles.
for example
IsInRole("CreateUser")
Previous to this i could assign the Activities (Roles) to the authenticated user after successful login
My only real concern with this is that by doing this when i authenticate the user and build the authentication cookie it will include alot (potentially) of Roles for each user.
for example i currently have 60 activities in my system (but this could increase as we add more features - each feature is in itselve a new activity)
If the authentication cookie has to carry approx 60+ roles (activities) would that cause any known issues?
Can anyone suggest an alternative approach ?
You may want to look into IdentityModel framework. It has the base class for building a custom Authorize module to verify permissions based on Resource-Action pattern. But this is built for .NET 4.5, not sure what your platform is.
.NET 4.5 also includes SessionAuthenticationModule (SAM) for web authentication. SAM can cache the roles between user calls, so that you don't have to send them back and forth in a cookie. Here is some more information on how it works.
Use Operations and Permissions, as described in Ayende's blog. He has lots of articles on the topic.
http://ayende.com/blog/3109/rhino-security-overview-part-i
http://ayende.com/blog/tags/rhino-security
What you want is a capability list approach.
The solution to this is a mapping of roles to capabilities, similar to this:
>Online Anon User Admin
Article ReadOnly ReadWrite ReadWrite
Article.List ReadOnly ReadOnly ReadOnly
Article.Edit Hidden ReadWrite ReadWrite
Article.Delete Hidden ReadOnly ReadWrite
Article.Title.Edit * * ReadWrite
In practice, these will be your coordinates:
>(system state)
The system may be "Online, Offline, Maintenance" and maybe more.
Use the initial > to find the start of your matrix in the file (you'll have many of these). In C# you'll have an enum.
On the same line are the roles:
Anon User Admin
Then on the left side you'll have the capabilities scoped into namespaces and actions:
<item>
<item>.<action>
<item>.<field>.<action>
<item>.<field>.<value>.<action>
The cells will contain one of these values:
Hidden, ReadOnly, ReadWrite or *
The * will mean "inherit" from the parent item or field.
This way you'll be able to fine-tune the permissions based on items, actions, roles and the current system state.
A simple parser translating the list into an in-memory structure will do. Don't put this on a DB, it will be a pain. Keeping it on the text-file/in-memory level is better. Add a FileSystemWatcher to read that file whenever it is changed for additional functionality and leverage lazy loading. Also, store it in Application state memory, not in a session.
Remember: the default will be Hidden (not even read access, the item/action will be completely inaccessible to that role.
Your real concern will then be which roles you'll really need (in my experience a role pretty much maps to an UML actor, maybe with some slight variances), and what the items/fields/values and actions really are. When you write an item you can really mean a group of items. There is no need to map the capability list directly unto a database/entity or code structure. The capability list is on a higher language level, it is semantic and bound to the domain, not to the code (I want to stress this because it's the real power behind this approach).
Once you have implemented this approach with a simple parser and helper object (Information Expert Principle is well advised, avoid Singletons) you'll be able to reuse it in many applications.
My website has forms authentication, and all is well. Now I want to create a subdirectory and have it also password-protected, but! I need the subdirectory to use a completely different set of logins/passwords than the whole website uses.
Say, for example, I have users for the website stored in the "Users" table in a database. But for the subdirectory, I want the users to be taken from the "SubdirUsers" table. Which probably has a completely different structure.
Consequently, I need the logins to be completely parallel, as in:
Logging into the whole website does not make you logged into the subdirectory as well
Clicking "logout" on the whole website does not nullify your login in the subdirectory
And vice versa
I do not want to create a separate virtual application for the subdirectory, because I want to share all libraries, user controls, as well as application state and cache. In other words, it has to be the same application.
I also do not want to just add a flag to the "Users" table indicating whether this is a whole website user or the subdirectory user. User lists have to come from different sources.
For now, the only option that I see is to roll my own Forms Auth for the subdirectory.
Anybody can propose a better alternative?
I think you can use this code to validate user with any provider
if (Membership.Providers["myprovider"].ValidateUser("USER", "PWD")) {
//your code
}
You can have a separate web.config file in the subfolder that includes only the validiation settings for that subfolder. Note that you must remove all the other settings, as there are some settings that can only be on application level.
<authorization configSource="alterativeSource.xml"/>
You will simply not be able to achieve this with FormsAuthentication only.
This problem scenario is perfect candidate for using HttpModules. HttpModules can intercept the Request and Response pipeline. You will need to write 2 HttpModules.
HttpModule for Authentication
HttpModule for Authorization
You can merge these modules into one later once your solution reaches in stable state and you are fairly able to manage the complexity.
In your solution, you will need to have a database mechanism that stores the subdirectory and user authorization and authentication mapping data. Your HttpModules can read these data take decision about the Requesting user.
You can start from here.
I could see a better answer if your users were in the web.config file, but since you're using users in a database you're pretty much going to have to use something besides forms Authentication. You'll need to set the sub directory to allow any users and then basically rebuild forms Authentication with sessions. You could make a sub class of the page class and use it to hold your all your routines to authenticate and redirect. Then you won't need to add anything to every page in the sub directory.
I know this is the answer you were probably hoping to avoid but forms Authentication is too simple a solution for this kind of complicated situation.
This can help you - numina.codeplex.com
Usually "authorization" is used after login to determine which directories, resources, etc can be used by the given user.
Have you looked at creating a role for the "main" directory and a second role for the "sub" directory and then applying the authorization tag (i.e. in the web.config)? You will need to implement an authorization provider, but that sounds like it might be a better long term solution than having multiple user tables.
Clarification Regardless of authorization (i.e. credential check or password, etc) you would still need to define the user roles somewhere, so for the sake of argument lets assume a "user table". (Nothing stops this from being an XML file in isolated storage if you wish.)
NB It doesn't actually matter that the users come from different sources. This should be reflected in the schema for the user table (i.e. a flag or another column, etc). If you fight this common pattern you will likely end up doing more work in the long run.
When there is one exception, there is likely to be another in the future....
I've not tried this but I think it would work.
You can have two membership providers (i.e., ASPNETDB_1 and ASPNETDB_2.)
These are specified in the membership provider section of the web.config. So you need a separate web.config in each subdirectory, which I know you can do.
In the root of the site I guess you would not have forms authentication. You could have just a start page that asks the user to choose which subdirectory (or you can just use subdomains (firstdir.mysite.com, secondir.mysite.com) or http:/mysite.com/firstdirectory or http:/mysite.com/secondirectory.
I am not sure of the advantage of this method over virtual directories, though, except that the root can contain some ASP programs that don't require authentication.
I understand you are looking for an "out of the box" solution and don't want to "roll your own". However;the standard membership provider does allow you to establish a profile for each user -- then it is really easy to setup one user maintenance form with a listview for each of your separate users maintenance functions and filter by role or by profile value (e.g., organizational ID). Using the membership provider classes, I personally found this very easy to do out of the box (maybe an hour of creating maintenane forms if that using all drag/drop controls, SqlDatasource + listview -- no VB or C coding required). But, separate providers and webconfigs would do the trick as well.
I'm building a SaaS app and have some issues in dealing with authorization and ASP.NET MVC. I have a previous question and this is kind of taking a cue from comments there. I need to provide somewhat granular security (e.g. lots of permissions) for each user. I realize that any discretionary system can be modeled as a roles system by just creating more roles. But that's a lot more roles than I want to deal with. I don't think roles is going to work for me and would like to work more at the permissions level.
I know the standard response to any question dealing with ASP.NET and authorization is create all your application users as Windows users and implement the ASP.NET Membership Provider. One issue, I'm not going to create Windows users. My question is can the standard ASP.NET MVC AuthorizeAttribute and AuthorizeCore be made to fit with a permissions model?
Also, apparently, the impetus here is really that ASP.NET MVC Caching will break a custom security implementation. Obviously, I don't want my pages to run slowly but I'm not sure I want this caching at all. I'm building a business application; is caching everything really appropriate? It seems that caching would just make concurrency problems much more difficult than they already are. For example, if I am caching all of my customer info pages, including the edit pages, then won't I be defeating any concurrency controls I would have in place (say, timestamp checking)?
If I were you I wouldn't create the users as Windows users, but rather store them in a SQL database. So you now have complete control over how you want to associate your security needs with your users.
Once you do that you can then create a custom security filter by creating a class that implements IAuthorizationFilter. That way you have the control you want to do whatever validation you want, roles based, permissions based, day of the week based, whatever.
You then just attribute your service methods with your new custom security filter, and pass along whatever info you need to ensure that the calling user has the appropriate rights/roles to execute the method.
First of all, you do certainly not need to make application users windows users. the default out of the box MVC has them as users stored in a sql database.
Edit Pages typically should not be cached as they will not really be loaded multiple times with the same data within the cache lifespan. my thought process is that MVC is easy enough to add caching that I would build it out first then performance test to see if it is even a necessary step. (Remember that unless you are looking at large large numbers of client connections then it is typically more economical to make a slightly less performant code and beef up the server hardware.
You do not need to create Windows users to use the ASP.NET Membership provider, it uses SQL tables to store the membership objects. Yes, you can use the Authorize attribute with the membership provider, for example, in a page that only "admins" can edit, you'll use the authorize attribute as follow:
[Authorize(Users = "Admin")]
Also, you don't want to be caching pages where users are going to be editing data, use caching (and you can do it a lot) in areas designated for anonymous users - users with no edit rights.
Hope this helps.