分享

MVC3 Custom AuthorizeAttribute

 Wiley Library 2011-10-12

MVC3 Custom AuthorizeAttribute

Posted by Jens in ASP.NET - MVC3

When coding websites in MVC3 it dosent take long before you realize you want a custom membership provider to handle your user logins. Once you have gotten this to work it is an even shorter time before you want to create your own custom attributes to apply to your Controller methods.

One example of a built in attribute is

1
[Authorize]

Adding this just before the Controller forces users to log in before they can use the specific part of the website the controller represents, redirecting them to the logon page before they can proceed.

But what if you wanted to make your own attribute that did something special that you could define?
Turns out its quite easy to do.

I Just finished making my own custom attribute that makes sure the user is in a specific role.

1
[CustomAuthorize(RequiredRole = "Admin")]

First off let me show you my models:

Here is a slimmed down version of my user model:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class User : MembershipUser
    {
        public int ID { get; set; }
        public DateTime Created { get; set; }
        public DateTime LastLogin { get; set; }
 
        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength =2)]
        public String username { get; set; }
 
        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
        [DataType(DataType.Password)]
        public String password { get; set; }
 
        public virtual ICollection UserRoles { get; set; }
 
        public User()
        {
            UserRoles = new List();
        }
 
        public bool MemberOf(string RoleName)
        {
            return UserRoles.Count(r => r.RoleName == RoleName) > 0 ? true : false;
        }
}

As you can see my User model has a relation to a UserRole model:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class UserRole
{
    public int ID { get; set; }
    public int RoleID { get; set; }
    public String RoleName { get; set; }
    public String Description { get; set; }
 
    public virtual ICollection Users { get; set; }
 
    public UserRole()
    {
        Users = new List();
    }
}

In my example this role has been added

1
2
3
4
5
6
new UserRole
{
    RoleID = 10,
    RoleName = "Admin",
    Description = "The Administrators role"
});

Using a membershipprovider similar to the one discussed in a previous post I have added a new user

1
2
3
4
5
6
7
8
9
10
11
12
13
MembershipProvider Membership = new AccountProvider();
MembershipCreateStatus createStatus;
 
Membership.CreateUser("admin", "123123", null, null, null, true, null, out createStatus);
UserRepository users = new UserRepository();
 
User u = context.Users.First(us => us.username == "admin");
 
if (u != null)
{
    UserRole ur = context.UserRoles.First(r => r.RoleID == 10);
    u.UserRoles.Add(ur);
}

Once we have something similar to that set up the actual attribute part to make sure a user is in a specific role is quite easy to set up. What we need is a properly named class that inherits from

1
AuthorizeAttribute

I created a new file called

1
HandleAuthorizeAttribute.cs

and wrote the following code in it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    DatabaseConnection _db = new DatabaseConnection ();
    public string RequiredRole;
    public int YourCustomValue;
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null) throw new ArgumentNullException("httpContext");
        if (httpContext.User.Identity.IsAuthenticated == false) return false;
        try
        {
            User user = _db.Users.Include("UserRoles").Single(u => u.username == httpContext.User.Identity.Name);
            return user.MemberOf(RequiredRole);
        }
        catch (Exception)
        {
            return false;
        }
    }
}

And thats it, now you can use your new shiny tag to protect your pages :)

1
2
3
4
5
[CustomAuthorize(RequiredRole = "Admin")]
public ActionResult ProtectedPage()
{
    return View();
}

You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约