当前位置:网站首页>【鉴权/授权】自定义一个身份认证Handler
【鉴权/授权】自定义一个身份认证Handler
2022-04-23 03:02:00 【dotNET跨平台】
微信公众号:趣编程ACE
关注可了解.NET日常开发技巧。如需源码,请公众号留言 [源码];
上文回顾
【鉴权/授权】一步一步实现一个简易JWT鉴权自定义身份验证CustomerAuthenticationHandler使用
上篇文章我演示了如何利用.net core 里面内置的验证方案-Bearer 进行身份验证,本文通过一个简单的例子来实现自定义身份验证流程。
超清观看哦~
首先创建一个登录服务
里面有三大步骤
1//Step1: 登录接口 需要在内置容器里面依赖注入
2public interface ICustomerAuthentication
3{
4 ...
5}
6
7// 接口的实例
8public class CustomerAuthentication : ICustomerAuthentication
9{
10 // Step2:提供一个登录方法
11 public string Login(string userName, string password)
12 {
13
14 }
15}
16
17// Step3: 容器依赖注入
18builder.Services.AddSingleton<ICustomerAuthentication,CustomerAuthentication>();
登录接口实现
1// 相当于在内存里面定义一个用户对象集合 模拟从数据库查询获取用户对象 方便check
2private readonly IDictionary<string,string> users = new Dictionary<string,string>
3{
4 {"p1","a1"},
5 {"p2","a2"},
6};
7// 存放token集合
8private readonly IDictionary<string,string> tokens = new Dictionary<string,string>();
9public IDictionary<string,string> Tokens =>tokens; // 实现接口 并初始化
10
11public string Login(string userName, string password)
12{
13 // check 用户真实存在
14 if(!users.Any(u=>u.Key==userName && u.Value==password))
15 {
16 return null;
17 }
18 // create token 通过一个Guid 类型的数据来代替token 仅为演示
19 var token = new Guid().ToString();
20 tokens.Add(token,userName);
21 return token ;
22}
创建一个自定义CustomerAuthenticationHandler类
1public class CustomerAuthenticationHandler :AuthenticationHandler<BasicAuthenticationOptions>
2{
3 ...
4}
其中CustomerAuthenticationHandler需要继承AuthenticationHandler接口,这个接口需要一个用于身份验证的Options配置类,所以需要定义一下BasicAuthenticationOptions 继承AuthenticationSchemeOptions
1public class BasicAuthenticationOptions :AuthenticationSchemeOptions
2{
3
4}
实现HandleAuthenticateAsync方法
1protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
2 {
3 // throw new NotImplementedException();
4 if(!Request.Headers.ContainsKey("Authorization"))
5 {
6 return AuthenticateResult.Fail("UnAuthorized");
7 }
8
9 // 获取请求头里面 Authorization对应的value
10 string authenticationHeader = Request.Headers["Authorization"];
11 if(string.IsNullOrEmpty(authenticationHeader))
12 {
13 return AuthenticateResult.Fail("UnAuthorized");
14 }
15 if(!authenticationHeader.StartsWith("Bearer",StringComparison.OrdinalIgnoreCase))
16 {
17 return AuthenticateResult.Fail("UnAuthorized");
18 }
19 // 获取token
20 string token = authenticationHeader.Substring("bearer".Length).Trim();
21 if(string.IsNullOrEmpty(token))
22 {
23 return AuthenticateResult.Fail("UnAuthorized");
24 }
25
26 try
27 {
28 // 验证token 调用下方ValidateToken() 这个方法
29 return ValidateToken(token);
30 }
31 catch (System.Exception ex)
32 {
33 // 记录日志
34 return AuthenticateResult.Fail("UnAuthorized");
35 }
36 }
37
38private AuthenticateResult ValidateToken(string token)
39 {
40 var validateToken = _customerAuthentication.Tokens.FirstOrDefault(t=>t.Key ==token);
41 if(validateToken.Key is null )
42 {
43 return AuthenticateResult.Fail("UnAuthorized");
44 }
45 var claims = new List<Claim>
46 {
47 new Claim(ClaimTypes.Name,validateToken.Value)
48 };
49
50 var identity = new ClaimsIdentity(claims,Scheme.Name);
51 var principle = new GenericPrincipal(identity,null);
52 var ticket = new AuthenticationTicket(principle,Scheme.Name);
53 return AuthenticateResult.Success(ticket);
54 }
该方法返回一个AuthenticateResult类型的对象来表示身份验证是否成功,如果成功,需要将这个票据返还给用户。
那么为啥需要票据呢?因为我们在Http传输协议下,需要保证附加在请求头或者请求参数的内容的安全性,所以需要将principal对象包裹成AuthenticationTicket对象,在后者里面我们可以增加一些安全配置。
DI中注册认证服务
1// 自定义验证 取名为一个 test 的Scheme方案
2builder.Services.AddAuthentication("test")
3 .AddScheme<BasicAuthenticationOptions,CustomerAuthenticationHandler>("test",null);
PS:本文来自社区群粉丝投稿~
版权声明
本文为[dotNET跨平台]所创,转载请带上原文链接,感谢
https://blog.csdn.net/sd7o95o/article/details/124287004
边栏推荐
- Centos7 install MySQL 8 0
- Microservices (distributed architecture)
- AC & A2C & A3C
- Regular object type conversion tool - Common DOM class
- The way to conquer C language
- 微软是如何解决 PC 端程序多开问题的——内部实现
- [format] simple output (2)
- Restart redis
- Close the computer port
- BLDC double closed loop (speed PI + current PI) Simulink simulation model
猜你喜欢
Niuke white moon race 5 [problem solving mathematics field]
Introduction and use of openfeign component
REINFORCE
HLS / chisel practice CORDIC high performance computing complex square root
Onenet connection process
Sonic cloud real machine tutorial
C# WPF UI框架MahApps切换主题
Windows MySQL 8 zip installation
[format] simple output (2)
Shell script learning notes - regular expressions
随机推荐
Niuke white moon race 5 [problem solving mathematics field]
Linux Redis ——Redis HA Sentinel 集群搭建详解 & Redis主从部署
The difference between encodeuri and encodeuricomponent
Win view port occupation command line
The way to conquer C language
Introduction and use of openfeign component
腾讯视频涨价:一年多赚74亿!关注我领取腾讯VIP会员,周卡低至7元
基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目
Kubernetes - detailed explanation of pod
Restart redis
tf. keras. layers. Timedistributed function
Basic SQL (VIII) data update operation practice
Use of MySQL command line client and common commands
Publish to NPM?
Solve the problem that PowerShell mining occupies 100% of cpu7 in win7
Golden nine silver ten interview season, you are welcome to take away the interview questions (with detailed answer analysis)
Error installing Mongo service 'mongodb server' on win10 failed to start
Regular object type conversion tool - Common DOM class
最通俗易懂的依赖注入之生命周期
Thoughts on the 2022 national network security competition of the national secondary vocational group (only one idea for myself) - network security competition questions (9)