baron
baron

Reputation: 11181

Authorization and authentication in MVC application

Authorization and authentication in MVC application

I have an internal web app developed in C# using MVC 2. I want to use AD roles/groups to do authorization. Thus I have 3 access group Admin, Basic, Readonly. The access to the application will be controlled through these groups.

Now when I hit an action/page of my MVC app, the requirements are:

1) Check level of access (is in either group Admin, Basic or Readonly)

2) If in a group - serve the page. If not - serve the 401 Unauthorized page.

I am probably confusing myself with the concepts authorization/authentication, but this is how it is set up so far (from answers, google and my own efforts flowing from this question:

public static class AuthorizationModule
    {
        public static bool Authorize(HttpContext httpContext, string roles)
        {
            ...
            //Check Configuration.AppSettings for the roles to check

            //using httpContext.User check .IsInRole for each role and return true if they are

            ...

            //other wise throw new HttpException(401,.....)
        }

        ...
    }

    public class AuthorizeByConfigurationAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //Essentially at the moment this is pretty much the same as AuthorizationModule.Authorize(HttpContext httpContext, string roles)
        }

    }

    //This code from http://paulallen.com.jm/blog/aspnet-mvc-redirect-unauthorized-access-page-401-page
    public class RequiresAuthenticationAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                filterContext.Result = new ViewResult {ViewName = "AccessDenied"};
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }
    }

The problems with this are that I seem to need to decorate my action methods twice now, ala:

[AuthorizeByConfiguration(Roles = "Admin, Basic, Readonly")]
        [RequiresAuthentication(Roles = "Admin, Basic, Readonly")]
        public ActionResult Index(string msg)
        {
            ...
        }

And the next problem is that it seems I have three separate methods all trying to do the same thing. I am overriding methods based on advice and not entirely sure how they were meant to work originally. How could I go about implementing my requirements?

edit: Since this is an IntrAnet app, all users who sign on with their network accounts will be able to access this app. I need to restrict the access so that only those who belong to certain Active Directory security groups can access this app

Upvotes: 3

Views: 2372

Answers (1)

CRice
CRice

Reputation: 12567

I have wrapped all the methods concerning auth with the interface IAuthorization.

Here is an example custom attrbiute you would need to add the Roles property and your own implementaion.

Attribute calls the filter itself for testability reasons.

public class SomeAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var filter = new SomeAuthorizeFilter(DependencyLookup.Resolve<IAuthorization>());
        filter.OnAuthorization(filterContext);
    }
}

public class SomeAuthorizeFilter : IAuthorizationFilter
{
    private readonly IAuthorization _authorization;

    public SomeAuthorizeFilter(IAuthorization authorization)
    {
        _authorization = authorization;
    }

    protected virtual ActionResult ResultWhenNotAuthenticated(AuthorizationContext filterContext)
    {
        //snip..

        //default
        RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary
                                                            {
                                                                {"action", "Index"},
                                                                {"controller", "Home"}
                                                            };
        return new RedirectToRouteResult(redirectTargetDictionary);
    }

    #region IAuthorizationFilter Members

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!_authorization.GetCurrentUserIdentity().IsAuthenticated)
        {
            filterContext.Result = ResultWhenNotAuthenticated(filterContext);
        }
    }

    #endregion
}

Upvotes: 2

Related Questions