3

How can I implement role based custom user authentication in asp.net MVC 3. Consider I have two table UserInfo(UserId, UserName, Password,RoleId) and Role(RoleId, RoleName).

I want to validate user from Database(UserInfo Table) and also want to retrieve roles from that table. And want to use like [Authorize(Roles="Admin")]

Need your help and idea....

0

1 Answer 1

7

You could use a custom authorize attribute and store the roles in the user data part of the authentication cookie. So for example inside your LogOn method once you have verified the credentials you could retrieve the roles for the given user from your database and store them into the user data:

// TODO: fetch roles from your database based on the username
var roles = "Admin|SomeRole";
var ticket = new FormsAuthenticationTicket(
    1, 
    username,
    DateTime.Now, 
    DateTime.Now.AddMilliseconds(FormsAuthentication.Timeout.TotalMilliseconds), 
    false, 
    roles
);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
{
    Domain = FormsAuthentication.CookieDomain,
    HttpOnly = true,
    Secure = FormsAuthentication.RequireSSL,
};

// Emit the authentication cookie which in addition to the username will
// contain the roles in the user data part
Response.AppendCookie(authCookie);

Then you could write a custom authorize attribute which will be used to read the authentication cookie and extract the roles information:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext.User.Identity.IsAuthenticated)
        {
            var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                var ticket = FormsAuthentication.Decrypt(authCookie.Value);
                var identity = new GenericIdentity(httpContext.User.Identity.Name);
                var roles = (ticket.UserData ?? string.Empty).Split('|');
                httpContext.User = new GenericPrincipal(identity, roles);
            }
        }

        return base.AuthorizeCore(httpContext);
    }
}

Now all that's left is to decorate your controllers/actions with this new attribute:

[MyAuthorize(Roles = "Admin")]
public ActionResult Foo()
{
    ...
}

UPDATE:

As requested in the comments section here's how you could override the HandleUnauthorizedRequest method in the custom authorize attribute so that if the user is not authorized to access a given action he is redirected to some error view instead of the login page:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    filterContext.Result = new ViewResult
    {
        ViewName = "~/Views/Shared/Unauthorized.cshtml"
    };
}
Sign up to request clarification or add additional context in comments.

9 Comments

I am very new in MVC3. Can I gen any sample solution(Project) on It.
@Hasibul, I would recommend you try implement it yourself and if you encounter difficulties don't hesitate to ask. I will be glad to help you.
Thanks for solution. I can do this. Here user information are written on cookie. If i close the browser without sign-out then cookie remains. so it is a problem. how i can overcome this? Is there any way to do above operation without using cookie.
@Hasibul, you could use a persistent cookie. Simply set the expiration date in the future on the authCookie and it will be stored on the client computer.
Is there any way to do above operation without using cookie? if i use [MyAuthorize(Roles = "Admin")] then "general" role users are moved to login page, i want to show them access denied message. how i can implement this. Thanks for help.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.