授权在.NET 中是指确定经过身份验证的用户是否有权访问特定资源或执行特定操作的过程。这就好比一个公司,身份验证(鉴权)是检查你是不是公司的员工,而授权则是看你这个员工有没有权限进入某个特定的办公室或者使用某台设备。
两个非常容易混淆的单词
- 鉴权Authentication --验证用户身份的过程,即确认用户是否是他们所声称的那个人
- 授权Authorization --看一下你有没有相应权限
鉴权使用体验
- 创建一个web api程序
- 在program.cs中使用鉴权授权中间件。builder.Services.AddAuthentication是告诉框架,如何进行鉴权,app.UseAuthentication();告诉框架,需要做鉴权。
- 新建一个Controller。在Action方法上面标记
[Authorize]
表示使用该接口需要鉴权,也可以直接将[Authorize]
特性放在Controller上面,对于不需要鉴权的Action上面放置[AllowAnonymous]
- 未登录时直接访问
/Test/UseCookie
,报错,原因是未登录直接跳转到/test/login
,而没有name和password参数,导致报400错误。
- 使用
/Test/Login?name=1&password=1
登录后,调用/test/login
,访问成功。
理解鉴权授权
常见的鉴权方式有Cookie、JWT,其实无论是什么鉴权方式,都是一个套路,其本质就是HTTP是无状态的,每次请求都是新的,服务器不知道他是不是之前的那个请求,所以鉴权授权都是分3步:
- 请求服务端,获取凭证
- 再次请求服务端,带上第一步获取到的凭证
- 服务端识别凭证, 判断是否允许访问
自定义鉴权
其实框架给我们封装好了很多鉴权方式,为了搞清原理,我们来个自定义鉴权。整个鉴权流程就是读取凭证—解析凭证—检验凭证----保存并向下一个管道传递。
- 新建一个类,继承自
IAuthenticationHandler
- 在program.cs中删除其他鉴权设定,增加以下设定
- 在控制器中新增一个Action来验证登录
当访问/CustomLogin?UrlToken=abc
时,正确访问,并打印出
授权的使用
授权检测可以有两层,1:没有任何要求,只要登录有凭证就行。2:要求用户有相应的权限才行
授权的三个属性
- Role角色
- Policy策略
- AuthenticationSchemes方案
角色Role
单角色
直接加上Roles =“Admin”
多角色
Admin和User都可以,满足一个就可以
如果是需要既能满足Roles ="Admin"又能满足Roles =“User”,则】
注意:这里的Roles需要在生成凭证的时候使用ClaimTypes.Name
的方式,而不能是new Claim(“Role”, “user”)
角色是最通用最简单的使用方式,但是不能满足个性化需求
策略Policy
Policy支持更灵活的自定义策略
直接使用特性标注[Authorize(Policy = "AdminPolicy")]
自定义Requirement
可以单独写一个Requirement
直接使用AddRequirements
使用
Policy的多条件组合
第一种方式
- And
直接在策略里增加即可
- Or
第二种方式(推荐)
注意:这种方式的“与,或”是通过写不写context.Fail()
来确定的。
- 结合自定义Requirement的方式,先建立一个父类
- 集成父类,设置条件,此处我们可以验证QQ邮箱和搜狗邮箱
- qq邮箱
- sougou邮箱
- 在Program.cs中使用ioc进行注册
- 在策略中增加
- 使用
多Scheme
- 在progress.cs中增加两个鉴权设置,一定要注意前后顺序,后面的会覆盖前面的
- 增加Action
- 先登录获取cookie,
/Test/Login?name=1&password=1
,再访问/Test/MultiToken?UrlToken=abc
这样就能得到两个Scheme的认证信息
JWT的鉴权与授权
- nuget安装
Microsoft.AspNetCore.Authentication.JwtBearer
。 - Program中定义
- 在登录Action中生成一个token
- 使用
请求时,需要在请求头中Authorization:
中带上Bearer 生成的token
,注意Bearer后面有一个空格