I am trying to build a claims aware Application using
MembershipReboot library for authentication
Thinktecture.IdentityModel.45 for authorization.
As far as tutorials go, they are all adding Claims manually to the "UserClaims" Table (not sure which library added that), which contains the UserID, the Type of the Claim and the Value.
I would like to add the claims programmatically to this table, but I am not sure how to do this in a obvious way.
You can add/remove claims via the AddClaim/RemoveClaim API on the UserAccount class. See the SingleTenantWebApp sample for an example:
https://github.com/brockallen/BrockAllen.MembershipReboot/blob/master/samples/SingleTenant/SingleTenantWebApp/Areas/UserAccount/Controllers/HomeController.cs#L28
Related
What is the best way of dynamic authorizing users with their roles. Indeed I have some roles that changes overtimes and currently I have this code for some of my actions or contorllers:
[Authorize(Roles = "Admin,MainFedration,FederationUser")]
public string ConfirmAccident(int? id)
{ .... }
Then if a role add or change it's permission i should search and change most of actions and roles to config new permission.
What is the best way to remove this redundant work?
The only other way would be to configure the permissions each role has in a database and then subclass AuthorizeAttribute and overload the logic for how it determines which roles are allowed by utilizing the database-stored permissions.
However, it should be noted, that this is a problem mostly because you're using roles improperly. I see this all over, even in official Microsoft documentation, which is part of the problem. Something like "Admin" is a group; roles are different and should be things like "CanEdit". A group or a user can be assigned roles, so any user in the "Admin" group, would have the role "CanEdit". Then, you don't have to change the roles config on the action because the ability to edit is the ability to edit, no matter which users or groups have it.
Maybe you should take a look at how Access Control is organized: https://nsecurity.codeplex.com/. Here's a simple solution which outlines the principles of Access Control Entries, Access Control Lists, and how access to items, subject to security restrictions is set up. This way of (dis-)allowing users' access to certain items is much like the way it is organized in, say, Windows file system.
The idea is really simple: instead of giving user permissions (not) to do this or that, the items are guarded and access is granted/denied once a simple condition is satisfied. In other words, security is not geared towards users, but towards "securables". Or, keys are used to lock/unlock doors, but not to prevent users from moving around.
I've used FluentSecurity in another MVC application and its great, provides a slick implementation.
I now have a requirement to offer application wide roles, plus also provide additional permission control over individiual entities.
My application manages particular locations and a user may have permissions to perform actions at one or more locations, each location has a unique id. I'll need to check a user has a particular role for the location id (effectively adding another dimension to roles). I've got my schema mapped out, along with my repo/service layers.
I was wondering if someone has tackled this type of problem before and whether its worth me trying to solve with FluentSecurity or if I should validate the user has the role required for the location on each GET/POST request (controller or service layer).
I'm getting to achieve this in FluentSecurity I'll have to roll my own policy and capture the location id from the RequestContext.RouteData.
I haven't done exactly what you need to do, but creating a custom policy in FluentSecurity that handles your scenario should not be hard at all. If you feel it is, please let me know and I will have to fix that.
You can find more information on how to create custom policies here:
https://github.com/kristofferahl/FluentSecurity/wiki/Custom-policies
It sounds to me like you might want to split it into two custom policies. You then apply your custom policies like this:
configuration.For<SomeController>()
.AddPolicy<CustomPolicy1>()
.AddPolicy<CustomPolicy2>();
I'm using vaadin for my project.I have implemented the User authentication using vaadin appfundation plugin,I need to apply role base access(Authorization) to the my application,But I don't know how to implement this functionality in appfundation,I searched a lot on the internet but I couldn't find a good example for that ,If any one knows how to implement that function pleas let me know,As I understood I want to implement Resource ,Role interfaces in appfundation,Please help me to solve this problem.Thnxx
You need to start by initializing a the Permissions class using a PermissionManager. So the first question is, how are you going to store your permissions? For example, if you are going to store them using JPA and AppFoundation's persistence module, then you can use the provided JPAPermissionManager. To initialize the Permissions class, call
Permissions.initialize(application, new JPAPermissionManager());
If you are not going to use JPAPermissionManager or the MemoryPermissionManager, then you need to implement the PermissionManager interface yourself and initialize Permissions using it.
The next step is to implement the Role and Resource interfaces. The Resource interface has just one method you need to implement, getIdentifier, which returns a unique string for a resource. A resource is whatever you want to protect, for example, a view. The Role interface also has a getIdentifier method which needs to be implemented, you should return a string which identifies a specific role, for example, "admin", "normal user", "power user" etc. The Role interface also has some other methods for handling role relations.
Unfortunately, the documentation is uncompleted and the best source available is probably this wiki page http://code.google.com/p/vaadin-appfoundation/wiki/Authorization
You can also try to take a look at the tests for the Authorization module, those might give you an idea how to use the module :(
I have been thinking for a good while about how to tackle the problem of implementing an ID based user system while using ASP.NET MVC. My goals, much like StackOverflow's system are as follows:
Allow the users to change their nicknames without the "avoid duplicate" restriction.
Allow the users to authenticate via OpenID (not with password for the time being).
I wanted to avoid as much rework as possible, so I at first thought of using the membership, role and (perhaps) profile providers, but I found they were username based.
I thought of adapting the hell out of the SqlMembershipProvider, by using the username field to store the IDs and throwing UnsupportedException on password based methods and the like, just so as to be able to use the other systems. But it feels unwieldy and kludgy (if possible to do at all).
On the other hand, maybe I should roll up my own user system, but I'm not sure if even if I can't use the providers, I can still use some of MVC's features (plug my code in with MVC somewhere, I can think of AuthorizeAttribute off the top my head).
So I was wondering if anyone had run into the same design problem, and what solutions they had come up with.
The more detail the better!
I had to set up a quick membership system for a client, they had some requirements that didn't allow me to use the built-in right off the bat nor the time to build what they wanted. I have plans to eventually roll-out a complete membership management system, but like you, I needed something now. I went with the following plan, which will, eventually, allow me to swap out the built-in providers for my own - time constraints and deadlines suck:
I have my own Personal User Table (PT) - MembershipId, UserName, Email, superflous profile info. This is what the app uses for any user information. It's a class, it can be cached, saved in the http context, cookie - however you want to handle your user info.
I then set up the SqlProfileProvider for authentication, authorization, and roles. I don't use the profile provider (even for trivial settings) because it's a pain in MVC. I made no changes to the built-in providers. This is what I'm using for authentication and authorization.
When creating a user, my code does the following:
Check PT for user name and email, per my rules
Create Guid - MembershipId
Create MembershipUser, the MembershipId is the username (the email is irrelevant and not used), and user password, question and answer, etc.
Create the user in PT with the profile values and use MembershipId as the PrimaryKey.
On login, I get the MembershipId from PT, validate against Membership with the MembershipId and the password and I'm done..
When deleting a user, I do the following:
Check PT for user, make sure I can/should delete
Get MemberShipId
Use a transaction
Delete from PT
User Membership.DeleteUser(MembershipId, true) - this ensures that the user is deleted from teh membership and other aspnet_ tables
commit
And it works as expected :)
A few things:
User.Identity.Name will be the MembershipId (Guid). This is used for SignIn and Role management. My PT is where the user's info (save the password) is saved. I can change user names, emails, etc with no impact on Membership or Roles because Membership is based on the PrimaryKey from PT.
The signin requires an extra DB hit because you need to query PT to get the MembershipId to validate against (you could cache).
The built-in auth system is really heavy - if you look at the sprocs you will see all the hoops it goes through to validate a user. I'd recommend eventually getting away from it. But in a tight spot, it does a good job - and if you don't have a milion users, I don;t think it'd be a problem.
I didn't consider OpenId and I'm not sure how you would integrate it, although I think you could probably do the same thing as above and instead of validating against actual credentials (after they come back validated form OpenId) just log in the user using the MembershipId (don;t validate against Membership).
For me, the main point behind this was that the app uses a custom user model, allowing for changes to user name, email, names, etc. Without impacting the auth and roles. When I am ready to change to the complete system, I can change it without worrying about the impact to the app.
Kenji,
I would recommend looking at some of the existing OpenID providers for ASP.NET. It should be fairly easy to make them work with MVC.
Erick
Forgo the use of SqlMembershipProvider. The only thing it would really offer you is an out of the box admin interface. The rest that it brings would be a nuisance.
Just use the sql membership provider and add a stored proc to change the username at the database level.
I'm bit vague about how to start using the shiro plugin, after reading few documents. I decided against Nimble, as it comes with few tables and UI plugins.
I setup shiro plugin with wildcard realm, with my own tables. I may use permission based (rather tan role based) access control as it scales well. Now, the steps for it.
assign the permission string to the subject, and save it in the db
check the permission through isPermitted, hasPermission (or relevant tags in GSP).
Now,
1. when to use the accesscontrol through filter?
2. is there a closure injected into the controller where I can define the permission for the actions in it? I read somewhere about accessControl static closure on each controller, but not seems to be documented.
3. How do I create a typical access control scenario like only the creator of (something, a post etc) can delete it? One possibility is creating and persisting a permission string based on userid. to check the permission retrieve the object (post), get the userid and compare with subject.. seems bit complicated.. any easy implementation?
thanks a lot..
Babu.
1 when to use the access control security filter?
A. Use accessControl{true} when you want to limit access to controller actions to authenticated users.
B. Use accessControl() when you want to limit access to controller actions, regardless of parameter content, based on permissions "${controllerName}:${actionName}".
C. When you want to limit actions based on parameter content, e.g. only delete a domain object for which you have the delete permission "${name}:${id}:delete", you need to check isPermitted explicitly in the controller.
3 How do I create a typical access control scenario like only the
creator?
I would add a the necessary permission(s) to the user when the post is created, e.g. "post:${postId}:*" This way the permissions belong to users and/or roles, and not to arbitrary domain objects, as intended in the Shiro way of working. As opposed to file system permissions, which belong to files and directories instead of users.