2015年12月1日 星期二

[ASP.NET] Windows Authentication with Roles

 ASP.NET   Windows Authentication


Introduction

In ASP.NET, besides the windows authentication, the role management and permission settings are a must in the Web application. This article will show how to make a Windows authentication based web application with role permission and management.




Enviroment

l   Visual Studio 2015
l   MVC 5
l   Entity Framework 6


Implement


Create the Code-first database

We will need these database tables to keep the information of “User” and “Role”.

l   SmUsers
l   SmRoles
l   SmUserRoles  : The relations between Users and Roles.


[Table("SmUsers")]
public class SmUser : BaseEntity
{
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [StringLength(300)]
        public String SmUserId { get; set; }

        [Required]
        [StringLength(200)]
        public String Name { get; set; }

        [Required]
        [StringLength(300)]
        public String AdUserId { get; set; }

        [Required]
        public bool IsEnabled { get; set; }
}


[Table("SmRoles")]
public class SmRole : BaseEntity
{
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int SmRoleId { get; set; }

        [Required]
        [StringLength(300)]
        public string Name { get; set; }

        [StringLength(500)]
        public string Description { get; set; }

        public bool IsEnabled { get; set; }
}


[Table("SmUserRoles")]
public class SmUserRole : UowEntity
{
        [Key]
        [Column(Order = 1)]
        public String SmUserId { get; set; }
        [Key]
        [Column(Order = 2)]
        public int SmRoleId { get; set; }

        //Foreign Key
        [ForeignKey("SmUserId")]
        public virtual SmUser SmUser { get; set; }

        //Foreign Key
        [ForeignKey("SmRoleId")]
        public virtual SmRole SmRole { get; set; }


And of course, don’t forget to implement the System.Data.Entity.DbContext
After all done, create the database.




Override System.Web.Security.RoleProvider class

The System.Web.Security. RoleProvider is in the assembly : System.Web.ApplicationServices
You have to override and implement the functions within it.

Notice that we are using AD ID as the “user name”, but not the real name or the system name in the application. The following code lists one function example for you.

public class SmRoleProvider : RoleProvider, IDisposable
    {
        private String _applicationName = "My Application";
        private SmDbContext _dbContext = null;
        private SmUserService<SmUser> _userService = null;
        private SmRoleService<SmRole> _roleService = null;
        private SmUserRoleService<SmUserRole> _userRoleService = null;

        public SmRoleProvider()
        {
            this._dbContext = new SmDbContext();
            this._userService = new SmUserService<SmUser>(this._dbContext);
            this._roleService = new SmRoleService<SmRole>(this._dbContext);
            this._userRoleService = new SmUserRoleService<SmUserRole>(this._dbContext);
        }
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            try
            {
                var userNames = this._userRoleService.Get(
                    x => (x.SmRole.Name == roleName && x.SmUser.AdUserId == usernameToMatch)).ToList().Select(x => x.SmUser.AdUserId);
                if (userNames != null)
                    return userNames.ToArray();
                else
                    return null;
            }
            catch (Exception ex)
            {
                LogUtility.Logger.Error(ex, "FindUsersInRole.");
                throw;
            }
        }
}





Inject our RoleProvider

In WebConfig, set the injection information as following.

<system.web>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" />
    <!-- Windows authentication -->
    <authentication mode="Windows" />
    <authorization>
      <deny users="?" />
    </authorization>
    <!-- Role management injection-->
    <roleManager defaultProvider="SmRoleProvider" enabled="true">
      <providers>
        <add
            name="SmRoleProvider"
            type="JB.Sample.MvcSiteMap.Service.Provider.SmRoleProvider"
            applicationName="JB.Sample.MvcSiteMap" />
      </providers>
    </roleManager>
  </system.web>


OK, it’s done. Let’ s test it.


Set permission on your functions

Now you can easily use the Authorize attribute to give a permission control of the functions.


As you can see, my AD’s role is “Admin” not “User”, so I get this result below.




Of course, if the permission is set to [Authorize(Roles ="Admin")], then we can access it.



Reference




沒有留言:

張貼留言