当前位置: 移动技术网 > IT编程>开发语言>.net > asp.net core2.2多用户验证与授权示例详解

asp.net core2.2多用户验证与授权示例详解

2019年05月28日  | 移动技术网IT编程  | 我要评论

中国五百强排名,清爱阁,南印度洋地图

前言

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,如何有?

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对移动技术网的支持。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网