1,通过继承BasePage页实现角色权限控制
context.User中保存的信息就是相关的角色与权限信息。Context.User类型为System.Security.Principal.IPrincipal;
Context.User.Identity为System.Security.Principal.IIdentity,因此只要我们实现的上述的两个接口便可实现我们所需的方案
在传统的.NET中,我们可以通过
User.Identity.Name;//获取用户名 User.Identity.IsAuthenticated;//判断用户是否己验证 User.IsInRole("Admin");//判断用户是否含有指定角色
但这样的机制,在实际开发中,难以满足开发需要.仅仅通过User.Identity.Name;获取用户名,和User.Identity.IsAuthenticated;判断用户是否验证,是难以满足需要。如何获取用户更多信息,或者进行更详细的权限判断。
我们可以通过自定义Identity和Principal进行实现!
////// 自定义当前用户标识对象 /// public class MyIdentity:IIdentity { #region 用户属性(可自定义更多信息) private string _userName;//用户账号 private string _departmnet;//用户所在部门 private string _phone;//用户联系电话 #endregion /// /// 用户账号 /// public string UserName { get { return _userName; } } /// /// 用户所在部门 /// public string Departmnet { get { return _departmnet; } } /// /// 用户电话 /// public string Phone { get { return _phone; } } /// /// 构造函数,根据用户名 /// /// public MyIdentity(string UserName) { //根据UserName查询数据库获得以下数据 this._userName = "abc"; this._departmnet = "行政部"; this._phone = "123456"; } /// /// 构造函数,根据用户ID /// /// public MyIdentity(int UserID) { //根据UserID查询数据库获得以下数据 this._userName = "abc"; this._departmnet = "行政部"; this._phone = "123456"; } #region 基本属性 /// /// 返回验证方式 /// public string AuthenticationType { get { return "Form"; } } /// /// 是否验证 /// public bool IsAuthenticated { get { return true; } } /// /// 返回用户 /// public string Name { get { return _userName; } } #endregion } /// /// 当前用户安全上下文信息 /// public class MyPrincipal:IPrincipal { #region 属性 private IIdentity _identity;//用户标识 private ArrayList _permissionList;//权限列表 #endregion /// /// 返回用户权限列表 /// public ArrayList PermissionList { get { return _permissionList; } } /// /// 获取当前用户标识 /// public IIdentity Identity { get { return _identity; } } /// /// 当前用户是否指定角色(采用权限值方式,此处返回false) /// /// /// public bool IsInRole(string role) { return false;//返回false } /// /// 构造函数,用户名构造 /// /// public MyPrincipal(string UserName) { _identity = new MyIdentity(UserName); //以下权限根据UserName获取数据库用户拥有的权限值,此次省略 _permissionList = new ArrayList(); _permissionList.Add(1); _permissionList.Add(2); _permissionList.Add(3); _permissionList.Add(4); _permissionList.Add(5); } /// /// 构造函数,用户ID构造 /// /// public MyPrincipal(int UserID) { _identity = new MyIdentity(UserID); //以下权限根据UserName获取数据库用户拥有的权限值,此次省略 _permissionList = new ArrayList(); _permissionList.Add(1); _permissionList.Add(2); _permissionList.Add(3); _permissionList.Add(4); _permissionList.Add(5); } /// /// 判断用户是否拥有某权限 /// /// /// public bool IsPermissionID(int permissionid) { return _permissionList.Contains(permissionid); } } 上面我们己实现了自定义,Identity和Principal。 我们可以在页面这样使用Identity。 //页面中输出自定义用户信息 <%=(User.Identity as ContextUser.MyIdentity).Name %>//用户账号 <%=(User.Identity as ContextUser.MyIdentity).Phone %>//用户电话 <%=(User.Identity as ContextUser.MyIdentity).Departmnet %>//用户所在部门 自定义显示用户信息后,我们接着利用Principal进行权限验证和控制 在Asp.net Web模式下,使用方式: 首先,我们先做一个权限验证基类! /// ///权限验证基类 /// public class BasePaper:System.Web.UI.Page { public BasePaper() { // //TODO: 在此处添加构造函数逻辑 // } protected override void OnInit(EventArgs e) { BasePage_Load(); } /// /// 设置权限,默认值为0 /// public virtual int PermissionID { get { return 0; } } /// /// 验证方法 /// /// /// private void BasePage_Load() { //权限检查 #region 权限检查 bool Permission = true;//初始值为没有权限 //这一步很重要,要代替.NET的自身的User. HttpContext.Current.User = new ContextUser.MyPrincipal(HttpContext.Current.User.Identity.Name); if ((User as account.ContextUser.MyPrincipal).PermissionList.Contains(PermissionID)) { Permission = false;//验证通过 } if (Permission)//权限验证不通过 { Response.Clear(); Response.Write(""); Response.End(); } #endregion } } OK,到了验证页的时候了。 public partial class ascx_Add :BasePage { public override int PermissionID { get { return 13;//返回要验证权限值 } } protected void Page_Load(object sender, EventArgs e) { // } } 事实上,在Asp.net MVC模式,更容易对权限进行控制,可以进行更多的细化,对每个动作进行控制。 MVC模式下: 首先,先实现一个权限验证基类: /// /// 权限验证基类 /// 2011.7.3 /// public class BasePage : AuthorizeAttribute { /// /// 权限值 /// private int _permissionID = 0; /// /// 权限值 /// public int PermissionID { get { return _permissionID; } set { _permissionID = value; } } ////// 在过程请求授权时调用。 /// /// 对象包括控制器、HTTP 上下文、请求上下文、操作结果和路由数据。 public override void OnAuthorization(AuthorizationContext filterContext) { if (HttpContext.Current.User.Identity.IsAuthenticated) { //这一步很重要,要代替.NET的自身的User. ContextUser.MyPrincipal MyPrincipal = new ContextUser.MyPrincipal(HttpContext.Current.User.Identity.Name); HttpContext.Current.User = MyPrincipal; if ((!MyPrincipal.ISPermissionID(_permissionID)) && (_permissionID != 0)) { HttpContext.Current.Response.Clear(); HttpContext.Current.Response.Write(""); HttpContext.Current.Response.End(); filterContext.Result = new EmptyResult(); } } else { FormsAuthentication.SignOut(); HttpContext.Current.Response.Clear(); HttpContext.Current.Response.Write(""); HttpContext.Current.Response.End(); filterContext.Result = new EmptyResult(); } } } 回到控制器,进行权限验证 [BasePage(PermissionID = 13)]//返回要验证权限值 public ActionResult Index() { // } 无论对Asp.net Form或者Aap.net MVC,都在一个按钮级的权限控制, 那对于,按钮级的权限如何进行控制昵? 看下面代码 //控制删除按扭的显示 <% if((User as account.ContextUser.MyPrincipal).PermissionList.Contains(13) {%> "submit" name="button" id="button" value="删除" /> <%} %> 至此,如何实现自定义Identity和Principal,进行整合更多用户信息,和权限验证。 2,通过HttpMoudle注册来实现角色权限控制。继承接口和上面一样 创建一个User类实现IIdentity接口 重写相应的方法 public class User : IIdentity { private int _id; private string _userName; private string _password; private bool _isAuthenticated; #region properties public virtual int Id { get { return this._id; } set { this._id = value; } } public virtual string UserName { get { return this._userName; } set { this._userName = value; } } public virtual string Password { get { return this._password; } set { this._password = value; } } //是否通过认证 public virtual bool IsAuthenticated { get { return this._isAuthenticated; } set { this._isAuthenticated = value; } } //重写为用户ID public virtual string Name { get { if (this._isAuthenticated) return this._id.ToString(); else return ""; } } public virtual string AuthenticationType { get { return "CuyahogaAuthentication"; } } public User() { this._id = -1; this._isAuthenticated = false; } } 创建一个CuyahogaPrincipal类实现IPrincipal接口 public class CuyahogaPrincipal : IPrincipal { private User _user; // 返回一个现实IIdentity接口的user对象 public IIdentity Identity { get { return this._user; } } // 当前用户是否属于指定角色 在以后的权限认证中可以使用 也可以使用User类中的相关方法来代替 public bool IsInRole(string role) { foreach (Role roleObject in this._user.Roles) { if (roleObject.Name.Equals(role)) return true; } return false; } ///初始化 若user通过授权则创建 public CuyahogaPrincipal(User user) { if (user != null && user.IsAuthenticated) { this._user = user; } else { throw new SecurityException("Cannot create a principal without u valid user"); } } } 创建一个实现IHttpModule的AuthenticationModule类 public class AuthenticationModule : IHttpModule { private const int AUTHENTICATION_TIMEOUT = 20; public AuthenticationModule() { } public void Init(HttpApplication context) { context.AuthenticateRequest += new EventHandler(Context_AuthenticateRequest); } public void Dispose() { // Nothing here } //登录时 验证用户时使用 public bool AuthenticateUser(string username, string password, bool persistLogin) { //数据访问类 CoreRepository cr = (CoreRepository)HttpContext.Current.Items["CoreRepository"]; string hashedPassword = Encryption.StringToMD5Hash(password); try { //通过用户名密码得到用户对象 User user = cr.GetUserByUsernameAndPassword(username, hashedPassword); if (user != null) { user.IsAuthenticated = true; //string currentIp = HttpContext.Current.Request.UserHostAddress; //user.LastLogin = DateTime.Now; //user.LastIp = currentIp; // Save login date and IP 记录相关信息 cr.UpdateObject(user);更新用户授权通过信息 // Create the authentication ticket HttpContext.Current.User = new CuyahogaPrincipal(user); //通过授权 FormsAuthentication.SetAuthCookie(user.Name, persistLogin); return true; } else { //log.Warn(String.Format("Invalid username-password combination: {0}:{1}.", username, password)); return false; } } catch (Exception ex) { throw new Exception(String.Format("Unable to log in user '{0}': " + ex.Message, username), ex); } } /// /// Log out the current user.注销用户 /// public void Logout() { if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated) { FormsAuthentication.SignOut(); } } private void Context_AuthenticateRequest(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; if (app.Context.User != null && app.Context.User.Identity.IsAuthenticated)//若用户已经通过认证 { CoreRepository cr = (CoreRepository)HttpContext.Current.Items["CoreRepository"]; int userId = Int32.Parse(app.Context.User.Identity.Name); User cuyahogaUser = (User)cr.GetObjectById(typeof(User), userId);//得到对应的cuyahogaUser对象 cuyahogaUser.IsAuthenticated = true; app.Context.User = new CuyahogaPrincipal(cuyahogaUser);//将通过标准窗体认证的user替换成CuyahogaUser, cuyahogaUser包含更多的信息 } } } 登录时 protected void btnLogin_Click(object sender, System.EventArgs e) { AuthenticationModule am = (AuthenticationModule)Context.ApplicationInstance.Modules["AuthenticationModule"]; if (this.txtUsername.Text.Trim().Length > 0 && this.txtPassword.Text.Trim().Length > 0) { try { if (am.AuthenticateUser(this.txtUsername.Text, this.txtPassword.Text, this.chkPersistLogin.Checked)) { //通过认证 Context.Response.Redirect(Context.Request.RawUrl); } else { //认证失败 } } { } } } 退出登录用 protected void btnLogout_Click(object sender, System.EventArgs e) { AuthenticationModule am = (AuthenticationModule)Context.ApplicationInstance.Modules["AuthenticationModule"]; am.Logout(); Context.Response.Redirect(Context.Request.RawUrl); } 这样就实现了身份认证功能 然后可以方便的实现权限认证 在User类中实现相应的权限逻辑 如: 表示当前用户是否有权限浏览指定的节点 public bool CanView(Node node) { foreach (Permission p in node.NodePermissions) { if (p.ViewAllowed && IsInRole(p.Role)) { return true; } } return false; } 在Page代码中嵌入验证代码即可 User CuyahogaUser = this.User.Identity as User; if(CuyahogaUser.CanView()) { } 权限认证模块还是挺简单. 最后在web.config中对AuthenticationModule进行注册
转:https://blog.csdn.net/anihasiyou/article/details/79668267