asp.net core2.2 用户验证授权有很详细和特贴心的介绍,我感兴趣的主要是这两篇:

  1. cookie身份验证
  2. 基于角色的授权

我的项目有两类用户:

  1. 微信公众号用户,用户名为公众号的openid
  2. 企业微信的用户,用户名为企业微信的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

  1. 修改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");
    });
  2. 修改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");
}
  1. 返回类型为Task<IActionResult> ,因为懒得写View,顺手写了句return Content("OK");
  2. 从网站复制过来代码,AuthenticationProperties没有设置任何内容

运行起来以后不停的调用login,百度了半天,改了各种代码,最后把return Content("OK");改成return RedirectToAction("Index");一切OK!

揣摩原因可能是当 return Content("OK");时,自动调用AuthenticationPropertiesRedirectUri,而RedirectUri为空时,自动调用自己。也不知道对不对。

这时候重视起RedirectUri,本来就要返回到returnUrl,是不是给RedirectUri赋值returnUrl就能自动跳转?

确实,return Content("OK");时候自动跳转了,return RedirectToAction("Index");无效。

最后把Task<IActionResult> 改成Task ,把return ...删除,一切完美!(弱弱问一句,是不是原来就应该这样写?我一直在走弯路?)

求助

User有属性Identities,看起来可以有多个Identity,如何有?

ASP.NET Core2.2 多用户验证和授权的更多相关文章

  1. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分

    原文:使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)--第1部分 原文链接:https://www.codeproject.com/Articles/5160941/ASP- ...

  2. ASP.NET Web API身份验证和授权

    英语原文地址:http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-a ...

  3. ASP.NET WEBAPI 的身份验证和授权

    定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...

  4. 【翻译】asp.net core2.1认证和授权解密

    asp.net core2.1认证和授权解密 本篇文章翻译自:https://digitalmccullough.com/posts/aspnetcore-auth-system-demystifie ...

  5. asp.net core2.1认证和授权解密

    来源:https://www.cnblogs.com/pangjianxin/p/9372562.html asp.net core2.1认证和授权解密 本篇文章翻译自:https://digital ...

  6. Asp.net中基于Forms验证的角色验证授权

    Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活. Forms 验证方式对基于用户的验证授 ...

  7. asp.net2.0安全性(3)--验证与授权--转载来自车老师

    "验证"与"授权"是对网页资源安全管理的两道门. 验证(Authentication):检查用户是否是合法的用户.就像是网站大门口的保卫,服责验证使用的用户名和 ...

  8. 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权

    OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...

  9. ASP.NET MVC5学习系列——身份验证、授权

    一.什么是身份验证和授权 人们有时对用户身份验证和用户授权之间的区别感到疑惑.用户身份验证是指通过某种形式的登录机制(包括用户名/密码.OpenID.OAuth等说明身份的项)来核实用户的身份.授权验 ...

随机推荐

  1. stress负载生成器使用简介

    一.Stress工具原始网页: https://people.seas.harvard.edu/~apw/stress/ 二.Docker镜像的构建过程(dockerfile): progrium/s ...

  2. spring AOP AspectJ 定义切面实现拦截

    总结记录一下AOP常用的应用场景及使用方式,如有错误,请留言. 1.  讲AOP之前,先来总结web项目的几种拦截方式    A:  过滤器 使用过滤器可以过滤URL请求,以及请求和响应的信息,但是过 ...

  3. linux 内存-文档学习

    ptmalloc http://www.malloc.de/en/ tcmalloc https://github.com/gperftools/gperftools jcmalloc http:// ...

  4. 远程连接bat

    @Echo offSet SERVER=10.40.61.101Set USERNAME=AdministratorSet PASSWORD=Marvin2008 Cmdkey /generic:TE ...

  5. Monkey测试log的保存与分析

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  6. MATLAB 曲线形状,粗细,颜色使用大全

    通过改变R-G-B 的值改变线条的颜色: $$\tt\Large plot(x,y,'Color',[R~~G~~B]);$$ 通过改变$c\in[1,+\infty)$的值改变线条的粗细 $$\tt ...

  7. PAT 1136 A Delayed Palindrome

    1136 A Delayed Palindrome (20 分)   Consider a positive integer N written in standard notation with k ...

  8. python网络爬虫&&爬取图片

    爬取学院官网数据from urllib.request import * #导入所有request urllib文件夹,request只是里面的一个模块from lxml import etree # ...

  9. 【IDEA填坑】xml不编译

    今天在maven编译Springboot项目的时候,发现src/main/resources下的配置文件编译失败(就是war包中没有放入xml配置文件导致程序启动失败),经查询资料,发现新版本的IDE ...

  10. 收藏的博客 -- Qt/C++学习

    Qt Creator环境: 使用Qt Creator作为Linux IDE,代替Vim:实现两台Linux电脑远程部署和调试(一台电脑有桌面系统,一台电脑无桌面系统) 使用Qt Creator作为Li ...