Building CustomAuthorization in ASP.NET MVC

asp.net, asp.net-mvc, authorization, c#-4.0, custom-attributes

Solution

You don't need to create a custom attribute. You can use existing `AuthoriseAttribute` but what you should do is implement custom `Principal` class that will use your own roles from DB. In your `Principal` class you will implement IsInRole method:

public bool IsInRole(string role)
{
    if(this.Roles == null)
        this.Roles = DependencyResolver.Current
           .GetService<ISecurityService>()
           .GetUserPermissions(this.Identity.Name);

    return this.Roles.Any(p => p.Name == role);
}

You should set your custom `Principal` in Global.asax

    void OnPostAuthenticateRequest(object sender, EventArgs e)
    {
         // Get a reference to the current User 
        IPrincipal user = HttpContext.Current.User; 

        // If we are dealing with an authenticated forms authentication request         
        if (user.Identity.IsAuthenticated && user.Identity.AuthenticationType == "Forms") 
        { 
            // Create custom Principal 
            var principal = new MyCustomPrincipal(user.Identity); 

            // Attach the Principal to HttpContext.User and Thread.CurrentPrincipal 
            HttpContext.Current.User = principal; 
            System.Threading.Thread.CurrentPrincipal = principal; 
        }
    } 

Problem

In the `DB` i have `Role` and `User` entities with one to many relationship. What i am trying to do is to build custom authorization filter. All the tutorials that i have seen are using default `ASP.NET` membership. All i know is that i need to inherit `AuthorizationAttribute` but do not know which methods do i need to override and how to implement them. ``` public class UserAuth : AuthorizeAttribute { } ``` In the `DB`: Role ``` public class Role { [Key] public int RoleID { get; set; } [Required] public int RolenameValue { get; set; } [MaxLength(100)] public string Description { get; set; } // // // // // public Rolename Rolename { get { return (ProjectName.Domain.Enums.Rolename)RolenameValue; } set { RolenameValue = (int)value; } } public virtual ICollection<User> Users { get; set; } } ``` User ``` public class User { [Key] public int UserID { get; set; } [Required] [MaxLength(30)] public string Username { get; set; } [Required] [MinLength(5)] public string Password { get; set; } [Required] [DataType(DataType.EmailAddress)] public string Email { get; set; } [MaxLength(30)] public string FirstName { get; set; } [MaxLength(50)] public string LastName { get; set; } [DataType(DataType.Date)] public DateTime Birthdate { get; set; } public int GenderValue { get; set; } // // // // // // // public Gender Gender { get { return (ProjectName.Domain.Enums.Gender)GenderValue; } set { GenderValue = (int)value; } } public int RoleID { get; set; } [ForeignKey("RoleID")] public Role Role { get; set; } ```

Original source