【鉴权/授权】自定义一个身份认证Handler

微信公众号:趣编程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:本文来自社区群粉丝投稿~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值