Authorize with Roles in onion Architecture - asp.net-mvc

hello everyone
i have a project where am using ASP.NET Identity 2.0. in this project am following the Onion architecture.
the layers are :
1.UI: no reference to Owin or ASP.Net Identity
2.AuthenticationService:contains a wrapper for the asp.net identity usermanager.this wrapper implement an interface that lives in the Bal layer.this layer also contain my custom UserStore.
3.Dal: DbContext lives here.
4.Bal: contain Domaine entities and interfaces .no reference to Owin or ASP.NET identity or anything else.
5.DependencyResolver: Owin Startup is here plus some Ninject Modules and the NinjectWebCommon.So am Using Ninject.
till now everything is fine. users are happy creating accounts and ,they can login/logout/manage any time they want.the problem am facing now is with the Authorize(Role="rolename").it just doesn't work.
[Authorize(Users="pedro")]
[Authorize]
both of these works
[Authorize(Roles="Admin")]
this is one no.
in my Database i have users who belongs to the Role Admin.I am not sure why this doesn't work.mybe because i moved all the authentication stuff to another layer so the IPrincipal.IsInRole(string role) can't figure out how to check this anymore.
am working on creating a custom Authorize attribute or create some extensions. but i decided to seek your advices first.
Thank you for your time

well Here i am answering My Own Question.
Indeed the problem was because the Method User.IsInRole(or IPrincipal.IsInRole because User is an IPrincipal). Inspecting the code of AuthorizeAttribute Using Reflector Shows that this Attribute uses the IsInRole Method To Check if The Authenticated User Is In Role X or Xs.but here comes another question .why it can't do that , i mean why it can't find out if a user belongs to a specific role or not.
the problem come from the Cookie generated for the user.because roles are associated to the Cookie they need to be there so IsInRole can Find Them and this is where i made My mistake.I moved the Authentication and authorization to somewhere else but i didn't provide a way to embed the roles informations inside the cookie so the IsInRole (from User or from Roles) couldn't find them in order for the Authorize Attribute to do it's job as i wanted it to.so the good news is that i only needed to insert the roles inside the cookie somehow.
the better news is : ASP.NET Identity wich am using now support claims,and in 4.5 GenericPrincipal derives from ClaimsPrincipal wich in turn derive from IPrincipal,so i can work with claims rather than old fashion roles (wich we can still use if we want to).
well.if someone came across the same issue,i recommand the following:
1.Authorize Attribute needs that the cookie to contain all the informations you are trying to rely on (Roles,User Names).
2.use thinktecture Nuget rather than Authorize or ClaimsPrincipalPermission attributes wich gives you the pros of both of them.
3.Learn About Claims.yo will never regret it.

Related

Associating Data with authenticated user in ASP.NET MVC optimization

I am using ASP.NET WebAPI with the built in authentication and identity services that come with the Visual Studio template. I now have it that a user can access the system and be authenticated.
The next logical step is to allow the user to create records. Lets say the user can have a "Project". How can I associate the user with a project at the point the project is created? It seems logical that the project table will just store the user_id provided by User.Identity.GetUserId().
Now, say that a project consists of Tasks. By default the WebAPI will create a Tasks controller, where I post a task. I think I would need to inject some additional information (such as the project id) at the point of creating the task.
But, say someone wants to add a task a project that doesn't belong to them. I need to verify this by loading the project, and checking the user_id field. Now I am adding two repositories to my controller. This seems like a lot of work.
Is it my own laziness that makes this seem hard???
I think this might be a related question, as it seems like you are looking for record-level authorization.
MVC / ASP.Net Best Practice for Record-Level Authorization
There is merit also in using multiple repositories. See here for an example of use.
http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Here, you would wrap the multiple repositories up within the UnitOfWork class.
I hope this points you in the right direction.

Plug A Custom Membership And Role Provider Into MVC 4

I have a custom user database that's quite locked down. I can only access it through stored procedures. I need to get this database to work with MVC so here's what I have so far.
A Repository that accesses a class that can manipulate the database.
A Class that inherits ExtendedMembershipProvider and a class that inherits RoleProvider.
I now need to plug these Providers into MVC but this is where I'm struggling.
If I create a new MVC4 project based on the Internet Application Template then everything seems to be geared around SimpleMembership. I can't even see where in the web.config the providers are declared. I see the AccountController has a lot of references to the ModelState and WebSecurity but I'm not sure where or how I tell these to use my providers. As I'm not using EF I also have my own User and Role Models.
If I create a new MVC project based on the "Basic" template then I can see the providers in the web.config but there is no Account Controller so I'm not sure how to properly create this.
Any pointers would be greatly appreciated. My aim is to be able to use all the usual [AllowAnonymous] [Authorize] etc.. tags in the controllers + IsAuthenticated, User.IsInRole etc.... in my Razor view files.
Check this out
EFMVC.Web.Core
and you can use this approach for your role management too
Had the same issue using Razor.
see if this Helps :
http://ratiyaranmal.blogspot.co.il/2012/12/custom-membership-provider-mvc.html

ASP.NET MVC2 and MemberShipProvider: How well do they go together?

I have an existing ASP.NET application with lots of users and a large database. Now I want to have it in MVC 2. I do not want to migrate, I do it more or less from scratch. The database I want to keep and not touch too much.
I already have my database tables and I also want to keep my LINQ to SQL-Layer. I didn't use a MembershipProvider in my current implementation (in ASP.NET 1.0 that wasn't strongly supported).
So, either I write my own Membershipprovider to meet the needs of my database and app or I don't use the membershipprovider at all.
I'd like to understand the consequences if I don't use the membership provider. What is linked to that? I understand that in ASP.NET the Login-Controls are linked to the provider. The AccountModel which is automatically generated with MVC2 could easily be changed to support my existing logic.
What happens when a user is identified by a an AuthCookie? Does MVC use the MembershipProvider then?
Am I overlooking something?
I have the same questions regarding RoleProvider.
Input is greatly appreciated.
With MVC it is simple to bypass the Membership and Role provider framework altogether. Sometimes it is easier to do this than to implement custom Membership/Role providers, in particular if your authn/authz model doesn't quite fit the mold of those providers.
First, you should realize that you don't need to write everything from scratch, you can use the core Forms authentication API, which can be used independently of the Membership/Role provider framework:
FormsAuthentication.SetAuthCookie -
Call this after user has been
authenticated, specify the user name
Request.IsAuthenticated - Returns
true if SetAuthCookie was called
HttpContext.Current.User.Identity.Name - Returns the user name specified in the call to SetAuthCookie
So here is what you do in MVC to bypass the Membership/Role provider:
Authentication: In your
controller, authenticate the user
using your custom logic.If
successful, call
FormsAuthentication.SetAuthCookie
with the user name.
Authorization: Create a custom
authorize attribute (deriving from
AuthorizeAttribute) . In the
AuthorizeCore override, implement
your custom authorization logic,
taking the user in
HttpContext.Current.User.Identity.Name
and the roles defined in the Roles
property of the AuthorizeAttribute base class.
Note you can also define properties on your custom
authorization attribute and use that in your authorization logic.
For example you can define a property representing roles as enumerated values
specific to your app, instead of using the Roles property which is just a string.
Affix your controllers and actions with your
custom authorize attribute,
instead of the default Authorize
attribute.
Although you most likely can do this without a custom membership provider, I'm not sure that you save that much effort. Until I read this blog post I thought implementing one was hard, but it's really not. Basically you do this:
Create a class that inherits System.Web.Security.MembershipProvider.
MembershipProvider is an abstract class, so you are readily shown what methods need to be implemented.
The names are pretty self explanatory, so you can probably more or less copy your existing logic.
You might end up doing more than you need with this approach - but on the other hand, anything you might want to use now or in the future that requires a membership provider will already have its needs met.
The source of the SQLMembershipProvider is available here http://weblogs.asp.net/scottgu/archive/2006/04/13/442772.aspx. Take that as a base.
It looks a bit much at first, but you only have to implement the methods you need.
Yes the AuthCookie is used. Yes its a good idea to use the MembershipProvider, because it is well known by other developers.
There are thinks I dont like about it: For example It is not possible to have a transaction that spans the creation of a user by the membershipsystem and some other data in your own datbase. But still it works well.

How do I expose built-in security and user management to a MVC application?

I have built a MVC website on IIS6. I used the built-in ASP.NET Security without Membership, just the way it was implemented in the template solution. It is easy to secure a contoller or action, but now I need to expose the user management to an admin logged into the site. I understand that the builtin ASP controls for doing this are not "best practice" and are a dog to get working. So what is the best practice for offering user management through a ASP.NET MVC application?
I considered using the Entity Framework and wireing it up to the myriad of stored procs. but that seems awkward. I see options for AccountMembershipService and FormsAuthenticationService. That is what the existing project account controller uses. But, I am not fimilliar with either.
I can't help but think that this should have already been there from the project template. This is a fundamental part of any website and you were given 15%, why not the rest?
As far as I can tell, you are using SqlMembershipProvider as your Membership Provider implementation. I would strongly suggest that you have a look at some of the methods of MembershipUser and MembershipProvider classes (such as CreateUser, etc) to achieve what you are trying to do instead of working with the underlying database tables used for the implementation.
You can also have a look at this article for an in depth intro to ASP.NET's Membership, Roles, and Profile providers.
Check out this project at CodePlex: ASP.Net MVC Membership Starter Kit
I don't know about "best practice" but this is how I would do it (and how it is sort of written in "Professional ASP.NET MVC 1.0"):
You should have a custom (or the default) ProfileProvider and MembershipProvider in place for this to work.
Create a controller which handles all the member management actions eg. MemberAdminController
This controller should have the Authorize[Roles="Administrator"] attribute specified so all actions in this controller will only be handled if the user is in the Administrator role.
Now you can build the CRUD views and actions how you would like using only this controller.
I have user auth working in a somewhat sane manner now. The biggest hurdle to get over is that it IS ok to use the Membership classes, even though I am not using the Profile aspect of membership. It is easy to get the user name and do Membership.GetUser(UserName). Then you can do many things like Unlock, Approve/Disapprove, change the password and change password question/answer... all the basics I need.
Here are the basics:
'get current logged in user
Dim currentUser As MembershipUser = Membership.GetUser()
'get current logged in user name
Dim userName = currentUser.UserName
'get current user email
Dim userEmail = currentUser.Email
'get a user to edit
Dim editingUser = Membership.GetUser(UserName)
'set the user email
editingUser.Email = newEmail
Membership.UpdateUser(editingUser)
‘unlock user
editingUser.UnlockUser()
‘disapprove user
editingUser.IsApproved = False
Membership.UpdateUser(editingUser)
‘approve user
editingUser.IsApproved = True
Membership.UpdateUser(editingUser)
‘change pw
editingUser.ChangePassword(oldPw, newPw)
and that is mostly all there is too it
In MvcCms we used the RoleProvider out of the box but converted the membership provider over to entity.
http://mvccms.codeplex.com/SourceControl/changeset/view/56727#994414

How should I implement user membership in my ASP.NET MVC site?

I'm creating an ASP.NET MVC site and I need to implement login and membership functionality.
Is this something where I roll my own? I already have a members table in my database, should I create a username and password hash field and just check against it? What about keeping the user logged in with a cookie that expires?
Is this an instance when you would use ASP.NET's built in Membership service?
ASP.NET MVC neophyte seeks help.
When you create a new ASP.NET MVC site, it already has membership built in. The CodePlex project mentioned in the other reply is only needed in special cases, namely:
You are using an early beta of the MVC framework, which doesn't have the membership feature.
You want to use an authentication system like OpenID, which isn't supported "out-of-the-box" with MVC.
You want membership administration features not included "out-of-the-box"
However, like I said, basic membership functionality is already present in an MVC site. Just add the [Authorize] attribute to any action requiring login. This is regular forms authentication, so you configured in Web.config like a non-MVC site (specifying the database, etc.; there's lots of information on the web about this).
A default MVC site will contain an "Account" controller and views which you can customize to fit your needs.
To answer the obvious question, no, you should not "roll your own." Even if you need custom authentication, it would be better to create a regular ASP.NET membership provider than to create an entirely new membership framework.
Update: The CodePlex project was updated to work with MVC 1.0
If you want to use something safe to start off with, either use the new project's template membership or consider using http://www.codeplex.com/MvcMembership.

Resources