当前位置:网站首页>【鉴权/授权】自定义一个身份认证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
边栏推荐
- Gavl021, gavl281, AC220V to 5v200ma small volume non isolated chip scheme
- Source code and some understanding of employee management system based on polymorphism
- Deep q-network (dqn)
- tf. keras. layers. MaxPooling? D function
- Get together to watch (detailed version) eat a few cents a day
- C#语法糖空合并运算符【??】和空合并赋值运算符【 ??=】
- In redis cluster, the master node fails, and the IP changes after the master-slave switch. The client does not need to deal with it
- Codeforces round 784 (Div. 4) (a - H)
- Linux redis - redis database caching service
- Numpy stack function
猜你喜欢

How to write the expected salary on your resume to double your salary during the interview?

最通俗易懂的依赖注入与控制反转

tf. keras. layers. MaxPooling? D function

Linux redis - redis database caching service

Configuring Apache Web services for servers such as Tianyi cloud

AC & A2C & A3C

Golden nine silver ten interview season, you are welcome to take away the interview questions (with detailed answer analysis)

Slave should be able to synchronize with the master in tests/integration/replication-psync.tcl
![Introduction to ACM [inclusion exclusion theorem]](/img/3a/9bc2a972d7587aab51fceb8cd2b9bd.png)
Introduction to ACM [inclusion exclusion theorem]

最通俗易懂的依赖注入之生命周期
随机推荐
Thoughts on the 2022 national network security competition of the national secondary vocational group (only one idea for myself) - network security competition questions (10)
The express project changes the jade template to art template
Publish to NPM?
Numpy append function
Liunx foundation - zabbix5 0 monitoring system installation and deployment
Linux Redis——Redis 数据库缓存服务
Niuke white moon race 5 [problem solving mathematics field]
Airtrack cracking wireless network password (Dictionary running method)
JS using the parameters of art template
Encapsulate components such as pull-down menu based on ele
《信息系统项目管理师总结》第七章 项目沟通管理
How to use C language to realize [guessing numbers game]
Summary of software test interview questions
AC380V drop 5v12v24v200ma, UHV non isolated chip IC scheme
Cloud computing learning 1 - openstack cloud computing installation and deployment steps with pictures and texts (Xiandian 2.2)
基于多态的职工管理系统源码与一些理解
tf. keras. layers. Inputlayer function
Cherno_ Game engine series tutorial (5): 101~
Detailed explanation of distributed things
Huawei machine test question -- deformation of hj53 Yang Hui triangle