asp.net core2.2 多用户验证和授权
asp.net core2.2 和有很详细和特贴心的介绍,我感兴趣的主要是这两篇:
我的项目有两类用户:
- 微信公众号用户,用户名为公众号的openid
- 企业微信的用户,用户名为企业微信的userid
每类用户中部分人员具有“admin”角色
因为企业微信的用户有可能同时是微信公众号用户,即一个人两个名,所以需要多用户验证和授权。咱用代码说话最简洁,如下所示:
public class democontroller : controller { /// <summary> /// 企业微信用户使用的模块 /// </summary> /// <returns></returns> public iactionresult work() { return content(user.identity.name +user.isinrole("admin")); } /// <summary> /// 企业微信管理员使用的模块 /// </summary> /// <returns></returns> public iactionresult workadmin() { return content(user.identity.name + user.isinrole("admin")); } /// <summary> /// 微信公众号用户使用的模块 /// </summary> /// <returns></returns> public iactionresult mp() { return content(user.identity.name + user.isinrole("admin")); } /// <summary> /// 微信公众号管理员使用的模块 /// </summary> /// <returns></returns> public iactionresult mpadmin() { return content(user.identity.name + user.isinrole("admin")); } }
下面咱一步一步实现。
第一步 改造类startup
-
修改configureservices方法,加入以下代码
services.addauthentication ( "work" //就是设置一个缺省的cookie验证的名字,缺省的意思就是需要写的时候可以不写。另外很多时候用cookieauthenticationdefaults.authenticationscheme,这玩意就是字符串常量“cookies”, ) .addcookie ( "work", //cookie验证的名字,“work”可以省略,因为是缺省名 option => { option.loginpath = new pathstring("/demo/worklogin"); //设置验证的路径 option.accessdeniedpath= new pathstring("/demo/workdenied");//设置无授权访问跳转的路径 }).addcookie("mp", option => { option.loginpath = new pathstring("/demo/mplogin"); option.accessdeniedpath = new pathstring("/demo/mpdenied"); });
-
修改configure方法,加入以下代码
app.useauthentication();
第二步 添加验证
public async task worklogin(string returnurl) { var claims = new list<claim> { new claim(claimtypes.name, "userid"), new claim(claimtypes.role, "admin") //如果是管理员 }; var claimsidentity = new claimsidentity(claims, "work");//“,"work"”可以省略,因为是缺省名 var authproperties = new authenticationproperties { allowrefresh = true, //expiresutc = datetimeoffset.utcnow.addminutes(10), // the time at which the authentication ticket expires. a // value set here overrides the expiretimespan option of // cookieauthenticationoptions set with addcookie. ispersistent = false, //持久化保存,到底什么意思我也不太清楚,哪位兄弟清楚的话,盼解释 //issuedutc = <datetimeoffset>, // the time at which the authentication ticket was issued. redirecturi = returnurl ?? "/demo/work" }; await httpcontext.signinasync("work", new claimsprincipal(claimsidentity), authproperties); } public iactionresult workdenied() { return forbid(); } public async task mplogin(string returnurl) { var claims = new list<claim> { new claim(claimtypes.name, "openid"), new claim(claimtypes.role, "admin") //如果是管理员 }; var claimsidentity = new claimsidentity(claims, "mp");//“,"mp"”不能省略,因为不是缺省名 var authproperties = new authenticationproperties { allowrefresh = true, ispersistent = false, redirecturi = returnurl ?? "/demo/mp" }; await httpcontext.signinasync("mp", new claimsprincipal(claimsidentity), authproperties); } public iactionresult mpdenied() { return forbid(); }
第三步 添加授权
就是在对应的action前面加[authorize]
/// <summary> /// 企业微信用户使用的模块 /// </summary> /// <returns></returns> [authorize( authenticationschemes ="work" //缺省名可以省略 )] public iactionresult work() { return content(user.identity.name + user.isinrole("admin")); } /// <summary> /// 企业微信管理员使用的模块 /// </summary> /// <returns></returns> [authorize(authenticationschemes ="work",roles ="admin")] public iactionresult workadmin() { return content(user.identity.name + user.isinrole("admin")); } /// <summary> /// 微信公众号用户使用的模块 /// </summary> /// <returns></returns> [authorize(authenticationschemes ="mp")] public iactionresult mp() { return content(user.identity.name + user.isinrole("admin")); } /// <summary> /// 微信公众号管理员使用的模块 /// </summary> /// <returns></returns> [authorize(authenticationschemes ="mp",roles ="admin")] public iactionresult mpadmin() { return content(user.identity.name + user.isinrole("admin")); }
ctrl+f5运行,截屏如下:
最后,讲讲碰到的坑和求助
坑
一开始的验证的代码如下:
public async task<iactionresult> login(string returnurl) { var claims = new list<claim> { new claim(claimtypes.name, "userid"), new claim(claimtypes.role, "admin") //如果是管理员 }; var claimsidentity = new claimsidentity(claims, "work");//“,"work"”可以省略,因为是缺省名 var authproperties = new authenticationproperties { //allowrefresh = true, //ispersistent = false, //redirecturi }; await httpcontext.signinasync("work", new claimsprincipal(claimsidentity), authproperties); return content("ok"); }
- 返回类型为task<iactionresult> ,因为懒得写view,顺手写了句return content("ok");
- 从网站复制过来代码,authenticationproperties没有设置任何内容
运行起来以后不停的调用login,百度了半天,改了各种代码,最后把return content("ok");改成return redirecttoaction("index");一切ok!
揣摩原因可能是当 return content("ok");时,自动调用authenticationproperties的redirecturi,而redirecturi为空时,自动调用自己。也不知道对不对。
这时候重视起redirecturi,本来就要返回到returnurl,是不是给redirecturi赋值returnurl就能自动跳转?
确实,return content("ok");时候自动跳转了,return redirecttoaction("index");无效。
最后把task<iactionresult> 改成task ,把return ...删除,一切完美!(弱弱问一句,是不是原来就应该这样写?我一直在走弯路?)
求助
user有属性identities,看起来可以有多个identity,如何有?
上一篇: 3dMax长方体怎么添加蒙皮姿势?
下一篇: WPF实战案例-打印
推荐阅读
-
ASP.NET实现用户注册和验证功能(第4节)
-
ASP.NET MVC4入门教程(六):验证编辑方法和编辑视图
-
ASP.NET MVC4入门教程(六):验证编辑方法和编辑视图
-
在ASP.NET 2.0中操作数据之十九:给编辑和新增界面增加验证控件
-
asp.net core系列之模型绑定和验证方法
-
ASP.NET MVC5网站开发之登录、验证和注销管理员篇1(六)
-
Asp.net开发之webform图片水印和图片验证码的实现方法
-
asp.net core系列之模型绑定和验证方法
-
ASP.NET MVC5网站开发之登录、验证和注销管理员篇1(六)
-
详解ASP.NET Core和ASP.NET Framework共享身份验证