Search This Blog

Thursday, March 24, 2016

MVC Active Directory Attribute Based Authorization with example


MVC Active Directory Attribute Based Authorization with example


Active Directory based authorization in .NET is fairly easy. Just throw an attribute on a controller as follows:

[Authorize (Roles="AdGroup")]
public class HomeController : Controller 

Sometimes though you do not want to hard code a role in an attribute as you may want to add or remove roles at will. You may also want to change the roles based on whether you are in production or not. I like to keep my Active Directory roles either in a database or a web.config file so that others can change authorization on the fly. In order to have greater control over your authorization roles you need to extend the AuthorizeAttribute and override AuthorizationCore. You also need to override HandleUnauthorizedRequest in order to have a custom redirect page.
Web.Config
<appSettings>
  <add key="Authorization.site" value="Domain\GeneralGroupName"/>
  <add key="AdminGroup" value="Domain\AdminGroupName"/>
</appSettings>
 
<system.web>
  <identity impersonate="false"/>
  <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">   </roleManager>
  <authentication mode="Windows"></authentication>
  <authorization>
    <allow roles="Domain\GeneralGroupName"/>
    <allow roles="Domain\AdminGroupName"/>
    <deny users="*"/>
  </authorization>
</system.web>
 
 
Role based Authorization code

/// <summary>
    /// Redirects to the unauthorized page.
    /// </summary>
    public class AuthorizeSiteRedirect : AuthorizeAttribute
    {
        /// <summary>
        /// Authorization based on roles in web.config.
        /// </summary>
        /// <param name="httpContext" />The http context
        /// <returns>Whether a user is authorized.</returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //// In this example we use a web.config key.
            //// <add key="Authorization.site" value="Your comma separated Ad Group List"/>
            var roles = ConfigurationManager.AppSettings["Authorization.Site"];
return roles.Split(',').ToList().Any(role => httpContext.User.IsInRole(role.Trim()));
        }

        /// <summary>
        /// Redirects an unauthorized request to the unauthorized page.
        /// </summary>
        /// <param name="filterContext" />The filter context
       protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.Result = new RedirectResult("~/Unauthorized");
        }
    }
You can now add more authorization levels for example an Admin level.

        /// <summary>
    /// Redirects to the unauthorized page.
    /// </summary>
    public class AuthorizeAdminRedirect : AuthorizeSiteRedirect
    {
        /// <summary>
        /// Authorizes a user based on active directory groups.
        /// </summary>
        /// <param name="httpContext" />The http context</param>
        /// <returns>Whether a user is authorized.</returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var roles = ConfigurationManager.AppSettings["AdminGroup"]; 
           return roles.Split(',').ToList().Any(role =>  httpContext.User.IsInRole(role.Trim()));
        }
    }
Now all you have to do is add an attribute to your controller and you are done:
[AuthorizeSiteRedirect]
public class HomeController : Controller 

    /// <summary>
    /// Administration page for site settings.
    /// </summary>
[AuthorizeAdminRedirect]
public class AdminController : Controller
 
Please be aware that when you store you active directory groups in a location like your config file you need to be sure 
to trim whitespace from your group name. Otherwise httpContext.User.IsInRole will not work accurately. For example if User1 is in group Group1 then User.IsInRole(" Group1") will return false however User.IsInRole("Group1") will return true.
 
If your website is throwing unauthorized access like below:
Access is denied. Description: An error occurred while accessing the resources required to serve this request. The server may not be configured for access to the requested URL.

Error message 401.2.: Unauthorized: Logon failed due to server configuration.  Verify that you have permission to view this directory or page based on the credentials you supplied and the authentication methods enabled on the Web server.  Contact the Web server's administrator for additional assistance.
Then check your project properties like below. Generally you will get this issue with new web application created with VS 2013.
 
Visual Studio 2013  Ã  New Web Application à By default Windows Authentication is disabled and 
Anonymous is Enabled à Perform changes like below.
 
 

Popular Posts