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. Python入门基础学习记录(二)汇率案例学习记录

    一.汇总整理 1.操作 ①新建python文件 工程右键--new--python file 2.注意问题与知识点 >变量定义:直接写变量名即可,例如定义一个字符串并赋值123: rmb_str ...

  2. win10 mysql5.7.28 配置安装

    如果有服务,使用下面命令删除,管理员身份打开cmd : sc delete mysql 1.下载 https://dev.mysql.com/downloads/mysql/5.7.html 没有的O ...

  3. Spring的工具类StringUtils使用

    我们经常会对字符串进行操作,spring已经实现了常用的处理功能.我们可以使用org.springframework.util.StringUtils 工具类帮我们处理字符串. 工具类整理如下:   ...

  4. ideal 切换git和svn

    原文地址:https://blog.csdn.net/lixld/article/details/98851427 intellij ideal gi和svn切换: 之前项目是svn的,新的项目用了g ...

  5. SQL Server 2014:为什么数据库里的表提示“单元格是只读的”,不能修改?该如何处理?

    出现以上这种情况,首先看一下这个字段的属性“标识规范”是不是选了“是”,自增属性下是不能修改的,属于只读.

  6. openssl编译安装

    最新版本可以在这个网站下载: https://www.openssl.org/source/ wget https://www.openssl.org/source/openssl-1.1.1c.ta ...

  7. Java & PHP RSA 互通密钥、签名、验签、加密、解密

    RSA加密算法是一种非对称加密算法.在公开密钥加密和电子商业中RSA被广泛使用.RSA是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Le ...

  8. 【UOJ#22】【UR #1】外星人(动态规划)

    [UOJ#22][UR #1]外星人(动态规划) 题面 UOJ 题解 一道简单题? 不难发现只有按照从大往小排序的顺序选择的才有意义,否则先选择一个小数再去模一个大数是没有意义的. 设\(f[i][j ...

  9. DAX 第七篇:分组聚合

    DAX有三个用于生成分组聚合数据的函数,这三个函数有两个共同的特征:分组列和扩展列. 分组列是用于分组的列,只能来源于基础表中已存的列,分组列可以来源于同一个表,也可以来源于相关的列. 扩展列是由na ...

  10. docker 制作一个容器,并上传到仓库

    创建镜像的三种方法 1.基于已有的镜像的容器创建 启动一个容器并修改容器: docker run -it ubuntu:latest /bin/bash touch test 提交创建新镜像并查看制作 ...