2

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; }
Bip
  • 853
  • 4
  • 14
  • 27

1 Answers1

7

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; 
        }
    } 
Jakub Konecki
  • 44,070
  • 6
  • 84
  • 125
  • +1, I do it in the same way, except that I load all roles through my Authorization repository in `OnPostAtuthenticate`. – jgauffin May 25 '12 at 12:14
  • How to implement `MyCustomPrincipal`? :P EDIT: I mean, how to properly implement it. Only with `IsInRole()` ? – Bip May 25 '12 at 12:17
  • 1
    Derive from `GenericPrincipal` (http://msdn.microsoft.com/en-us/library/system.security.principal.genericprincipal.aspx) or implement `IPrincipal` interface – Jakub Konecki May 25 '12 at 12:20