1,Webform通过继承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");//判断用户是否含有指定角色
但这样的机制,在实际开发中,难以满足开发需要.我们需要获取更多信息,或者进行更详细的权限判断。
我们可以通过自定义Identity和Principal进行实现!
///<summary>/// 自定义当前用户标识对象
///</summary>publicclass MyIdentity:IIdentity
{
//用户属性(可自定义更多信息)
privatestring _userName;//用户账号privatestring _departmnet;//用户所在部门privatestring _phone;//用户联系电话///<summary>/// 用户账号
///</summary>publicstring UserName
{get { return _userName; } } ///<summary>/// 用户所在部门
///</summary>publicstring Departmnet
{get { return _departmnet; } } ///<summary>/// 用户电话
///</summary>publicstring Phone
{get { return _phone; } } ///<summary>/// 构造函数,根据用户名
///</summary>///<param name="UserName"></param>public MyIdentity(string UserName)
{
//根据UserName查询数据库获得以下数据
    this._userName = "abc";
this._departmnet = "行政部";
this._phone = "";
} ///<summary>/// 构造函数,根据用户ID
///</summary>///<param name="UserID"></param>public MyIdentity(int UserID)
{
//根据UserID查询数据库获得以下数据 this._userName = "abc";
this._departmnet = "行政部";
this._phone = "";
} #region 基本属性
///<summary>/// 返回验证方式
///</summary>publicstring AuthenticationType
{
get { return"Form"; }
} ///<summary>/// 是否验证
///</summary>publicbool IsAuthenticated
{
get { returntrue; }
} ///<summary>/// 返回用户
///</summary>publicstring Name
{
get { return _userName; }
}
#endregion
} ///<summary>/// 当前用户安全上下文信息
///</summary>publicclass MyPrincipal:IPrincipal
{ private IIdentity _identity;//用户标识 private ArrayList _permissionList;//权限列表 ///<summary>/// 返回用户权限列表
///</summary>public ArrayList PermissionList
{ get { return _permissionList; } } ///<summary>/// 获取当前用户标识
///</summary>public IIdentity Identity
{ get { return _identity; } } ///<summary>/// 当前用户是否指定角色(采用权限值方式,此处返回false)
///</summary>///<param name="role"></param>///<returns></returns>publicbool IsInRole(string role)
{ returnfalse; } ///<summary>/// 构造函数,用户名构造
///</summary>///<param name="UserName"></param>public MyPrincipal(string UserName)
{
_identity = new MyIdentity(UserName);
//以下权限根据UserName获取数据库用户拥有的权限值,此次省略
_permissionList = new ArrayList();
_permissionList.Add();
_permissionList.Add();
_permissionList.Add();
} ///<summary>/// 构造函数,用户ID构造
///</summary>///<param name="UserID"></param>public MyPrincipal(int UserID)
{
_identity = new MyIdentity(UserID);
//以下权限根据UserName获取数据库用户拥有的权限值,此次省略
_permissionList = new ArrayList();
_permissionList.Add();
_permissionList.Add();
_permissionList.Add();
} ///<summary>/// 判断用户是否拥有某权限
///</summary>///<param name="permissionid"></param>///<returns></returns>publicbool 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模式下,使用方式:
首先,我们先做一个权限验证基类!
///<summary>///权限验证基类
///</summary>publicclass BasePaper:System.Web.UI.Page
{
public BasePaper()
{ } protectedoverridevoid OnInit(EventArgs e)
{
BasePage_Load();
} ///<summary>/// 设置权限,默认值为0
///</summary>publicvirtualint PermissionID
{ get { return; } } ///<summary>/// 验证方法
///</summary>///<param name="sender"></param>///<param name="e"></param>privatevoid BasePage_Load()
{
//权限检查 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("<script language=\"javascript\">alert(\"对不起,你没有权限进入\");history.go(-1);</script>");
Response.End();
}
}
} OK,到了验证页的时候了。
publicpartialclass ascx_Add :BasePage
{
publicoverrideint PermissionID
{
get
{
return;//返回要验证权限值 }
} protectedvoid Page_Load(object sender, EventArgs e)
{ }
} 事实上,在Asp.net MVC模式,更容易对权限进行控制,可以进行更多的细化,对每个动作进行控制。
首先,先实现一个权限验证基类:
///<summary>/// 权限验证基类
/// 2011.7.3
///</summary>publicclass BasePage : AuthorizeAttribute
{
///<summary>/// 权限值
///</summary>privateint _permissionID = ; ///<summary
/// 权限值
///</summary>publicint PermissionID
{
get { return _permissionID; }
set { _permissionID = value; }
} ///<summary>/// 在过程请求授权时调用。
///</summary>///<param name="filterContext">对象包括控制器、HTTP 上下文、请求上下文、操作结果和路由数据。</param>publicoverridevoid 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 != ))
{
HttpContext.Current.Response.Clear(); HttpContext.Current.Response.Write("<script defer>window.alert('无权操作!');history.back();</script>"); HttpContext.Current.Response.End(); filterContext.Result = new EmptyResult();
}
}
else
{
FormsAuthentication.SignOut();
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Write("<script defer>window.alert('无权操作!或当前登录用户已过期!\\n请重新登录或与管理员联系!');</script>");
HttpContext.Current.Response.End();
filterContext.Result = new EmptyResult();
}
}
} 回到控制器,进行权限验证
[BasePage(PermissionID = )]//返回要验证权限值 public ActionResult Index()
{
// } 无论对Asp.net Form或者Aap.net MVC,都在一个按钮级的权限控制,
那对于,按钮级的权限如何进行控制昵? 看下面代码
//控制删除按扭的显示 <% if((User as account.ContextUser.MyPrincipal).PermissionList.Contains() {%>
<input type="submit" name="button" id="button" value="删除" />
<%} %> 至此,如何实现自定义Identity和Principal,进行整合更多用户信息,和权限验证。
,通过HttpMoudle注册来实现角色权限控制。继承接口和上面一样
创建一个User类实现IIdentity接口 重写相应的方法
publicclass User : IIdentity
{
privateint _id;
privatestring _userName;
privatestring _password;
privatebool _isAuthenticated;
#region properties
publicvirtualint Id
{
get { returnthis._id; }
set { this._id = value; }
}
publicvirtualstring UserName
{
get { returnthis._userName; }
set { this._userName = value; }
}
publicvirtualstring Password
{
get { returnthis._password; }
set { this._password = value; }
}
//是否通过认证publicvirtualbool IsAuthenticated
{
get { returnthis._isAuthenticated; }
set { this._isAuthenticated = value; }
}
//重写为用户IDpublicvirtualstring Name
{
get
{
if (this._isAuthenticated)
returnthis._id.ToString();
elsereturn"";
}
}
publicvirtualstring AuthenticationType
{
get { return"CuyahogaAuthentication"; }
}
public User()
{
this._id = -;
this._isAuthenticated = false;
}
}
创建一个CuyahogaPrincipal类实现IPrincipal接口
publicclass CuyahogaPrincipal : IPrincipal
{
private User _user;
// 返回一个现实IIdentity接口的user对象public IIdentity Identity
{
get { returnthis._user; }
}
// 当前用户是否属于指定角色 在以后的权限认证中可以使用 也可以使用User类中的相关方法来代替publicbool IsInRole(string role)
{
foreach (Role roleObject inthis._user.Roles)
{
if (roleObject.Name.Equals(role))
returntrue;
}
returnfalse;
}
///初始化 若user通过授权则创建public CuyahogaPrincipal(User user)
{
if (user != null && user.IsAuthenticated)
{
this._user = user;
}
else
{
thrownew SecurityException("Cannot create a principal without u valid user");
}
}
}
创建一个实现IHttpModule的AuthenticationModule类
publicclass AuthenticationModule : IHttpModule
{
privateconstint AUTHENTICATION_TIMEOUT = ; public AuthenticationModule()
{
} publicvoid Init(HttpApplication context)
{
context.AuthenticateRequest += new EventHandler(Context_AuthenticateRequest);
} publicvoid Dispose()
{
// Nothing here } //登录时 验证用户时使用publicbool 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);
returntrue;
}
else
{
//log.Warn(String.Format("Invalid username-password combination: {0}:{1}.", username, password));returnfalse;
}
}
catch (Exception ex)
{
thrownew Exception(String.Format("Unable to log in user '{0}': " + ex.Message, username), ex);
}
} ///<summary>/// Log out the current user.注销用户
///</summary>publicvoid Logout()
{
if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated)
{
FormsAuthentication.SignOut();
}
} privatevoid 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包含更多的信息 }
}
}
登录时
protectedvoid btnLogin_Click(object sender, System.EventArgs e)
{
AuthenticationModule am = (AuthenticationModule)Context.ApplicationInstance.Modules["AuthenticationModule"];
if (this.txtUsername.Text.Trim().Length > && this.txtPassword.Text.Trim().Length > )
{
try
{
if (am.AuthenticateUser(this.txtUsername.Text, this.txtPassword.Text, this.chkPersistLogin.Checked))
{
//通过认证 Context.Response.Redirect(Context.Request.RawUrl);
}
else
{
//认证失败 }
}
{
}
}
}
退出登录用
protectedvoid btnLogout_Click(object sender, System.EventArgs e)
{
AuthenticationModule am = (AuthenticationModule)Context.ApplicationInstance.Modules["AuthenticationModule"];
am.Logout();
Context.Response.Redirect(Context.Request.RawUrl);
}
这样就实现了身份认证功能 然后可以方便的实现权限认证
在User类中实现相应的权限逻辑 如: 表示当前用户是否有权限浏览指定的节点
publicbool CanView(Node node)
{
foreach (Permission p in node.NodePermissions)
{
if (p.ViewAllowed && IsInRole(p.Role))
{
returntrue;
}
}
returnfalse;
}
在Page代码中嵌入验证代码即可
User CuyahogaUser = this.User.Identity as User;
if(CuyahogaUser.CanView())
{
}
权限认证模块还是挺简单.
最后在web.config中对AuthenticationModule进行注册

转:https://blog.csdn.net/anihasiyou/article/details/79668267

.net使用IIdentity和IPrincipal实现自定义身份及权限认证【转】的更多相关文章

  1. kubernetes 身份与权限认证 (ServiceAccount && RBAC)

    Kubernetes中提供了良好的多租户认证管理机制,如RBAC.ServiceAccount还有各种Policy等.   ServiceAccount Service Account为Pod中的进程 ...

  2. 当shiro不进入自定义realm的权限认证方法时

    需要加入下面的一个bean @Bean public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){ DefaultAdvisorA ...

  3. shiro 身份授权+权限认证

    https://www.cnblogs.com/cmyxn/p/5825099.html

  4. webservice安全性之 SoapHeader自定义身份验证

    相信很多开发者都用过WebService来实现程序的面向服务,本文主要介绍WebService的身份识别实现方式,当然本文会提供一个不是很完善的例子,权当抱砖引玉了. 首先我们来介绍webservic ...

  5. [C#].Net Core下全局自定义身份过滤器使用AllowAnonymous属性

    假设一种情况:项目中需要做认证和权限控制,而且需要权限才能访问的控制器要远多于可以匿名访问的(类似AO系统那样,登陆了才能用). 那在每个控制器上加一个 [Authorize] 是能解决问题,反正正我 ...

  6. django 自定义身份认证

    自定义身份认证: Django 自带的认证系统足够应付大多数情况,但你或许不打算使用现成的认证系统.定制自己的项目的权限系统需要了解哪些一些关键点,即Django中哪些部分是能够扩展或替换的.这个文档 ...

  7. SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存

    项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)在pom.xml中添加依赖: <properties> <shi ...

  8. Spring Boot 使用 JWT 进行身份和权限验证

    上周写了一个 适合初学者入门 Spring Security With JWT 的 Demo,这篇文章主要是对代码中涉及到的比较重要的知识点的说明. 适合初学者入门 Spring Security W ...

  9. django身份认证、权限认证、频率校验使用及源码分析

    一. 身份认证源码分析 1.1 APIView源码的分析 APIView源码之前分析过https://www.cnblogs.com/maoruqiang/p/11135335.html,里面主要将r ...

随机推荐

  1. github README.md创建不了

    在项目主页上,点击‘Add a README’按钮,如下图: 进入编辑界面,编辑好内容后,提交按钮的状态为灰化不可点击,如下图: 不知道为什么会出现这种情况,但是我无意中点击了Ctrl+Enter竟然 ...

  2. 软件工程实践2019——idea表述及组队

    时间:2019-10-08 随堂 欢迎每个有想法的同学都积极参与idea表述,用心呈现你的心中所想.你心中热爱的,希望在软工实践项目中完成的项目作品.每个愿意表达idea的同学,都有一分钟时间来呈现作 ...

  3. 基于 K8s 做应用发布的工具那么多, 阿里为啥选择灰姑娘般的 Tekton ?

    作者 | 邓洪超,阿里云容器平台工程师, Kubernetes Operator 第二人,云原生应用标准交付与管理领域知名技术专家   导读:近年来,越来越多专门给 Kubernetes 做应用发布的 ...

  4. 分布式应用的未来 — Distributionless

    作者丨阿里云高级技术专家 至简(李云) 在技术变革推动社会发展这一时代背景下,大量支撑规模化分布式应用的技术创新.创造与创业应用而生,Could Native.Service Mesh.Serverl ...

  5. 数据持久化之Data Volume

    废话不多说直接操作 1.启动一个MySQL测试容器 [root@localhost labs]# docker pull mysql #下载MySQL镜像 [root@localhost labs]# ...

  6. SetApartmentState(ApartmentState state).Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process

    System.Threading.ThreadStateException: 'Current thread must be set to single thread apartment (STA) ...

  7. AdminLTE 3.0发布了

    在11月2日,作者正式发布了AdminLTE 3.0版本.该版本基于Bootstrap 4.x.使用Bootstrap 4.x的小伙伴可以愉快的使用AdminLTE. Github AdminLTE是 ...

  8. WPF MVVM框架(5)

    前面几章节所讲到的内容, 基本上属于前端XAML的使用方法, 那么本章及后面的章节, 则会侧重于UI与业务分离如何分离 . UI与业务逻辑之间的互操作性,, 下面将介绍WPF中, 比较主流的MVVM框 ...

  9. Java面向对象——相关基本定义

    Java面向对象——相关基本定义 摘要:本文简单介绍了面向对象的编程方式,以及与之有关的一些基本定义. 面向对象 什么是面向对象 面向对象编程是一种对现实世界建立计算机模型的一种编程方法.简称OOP( ...

  10. ASP.NET Core系列:依赖注入

    1. 控制反转(IoC) 控制反转(Inversion of Control,IoC),是面向对象编程中的一种设计原则,用来降低代码之间的耦合度. 1.1 依赖倒置 依赖原则: (1)高层次的模块不应 ...