前言
小项目中需要添加 Api 请求权限认证, 并且只是专用网络内使用,于是只想简单得认证下是否可以访问, 顺便也是一种学习的过程,简单记录一下
要点
实现 IAuthenticationHandler 接口:4 个方法
- 首先会调用 InitializeAsync 获取到 scheme 和 context
- 然后调用 AuthenticateAsync ,在这里获取 context 中的 Header 中需要传过来的验证信息,然后进行相关验证,根据不同的结果会分别调用 ChallengeAsync 或者 ForbidAsync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
public class HeaderAuth : IAuthenticationHandler { public AuthenticationScheme Scheme { get ; private set ; } public HttpContext CurrentContext { get ; private set ; } public Task<AuthenticateResult> AuthenticateAsync() { var token = CurrentContext.Request.Headers[GuidToken.GUID_TOKEN_KEY].ToString(); var (isValid, tokenEntity) = GuidToken.Valid(token); if (!isValid || tokenEntity == null ) { return Task.FromResult(AuthenticateResult.Fail( "未登录或授权已过期。" )); } // 生成 AuthenticationTicket AuthenticationTicket ticket = new AuthenticationTicket(tokenEntity.ToClaimsPrincipal(), Scheme.Name); return Task.FromResult(AuthenticateResult.Success(ticket)); } public Task ChallengeAsync(AuthenticationProperties properties) { CurrentContext.Response.StatusCode = ( int )HttpStatusCode.Unauthorized; return Task.CompletedTask; } public Task ForbidAsync(AuthenticationProperties properties) { CurrentContext.Response.StatusCode = ( int )HttpStatusCode.Forbidden; return Task.CompletedTask; } public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context) { Scheme = scheme; CurrentContext = context; return Task.CompletedTask; } } |
GuidToken 类就是我们自定义的 token 管理器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
public class GuidToken { public const string GUID_TOKEN_NAME = "MtGuidTokenAuthentication" ; public const string DEFAULT_AUTHENTICATION_TYPE = "local" ; public const int TOKEN_LENGTH = 32; public const string GUEST = "GUEST" ; public const string DEFAULT_ROLE = "USER" ; public const string DEFAULT_OPENID = "DEFAULT_OPENID" ; public const string GUID_TOKEN_KEY = "Token" ; private static int expireDuration = 0; public string OpenId { get ; set ; } public string Role { get ; set ; } public DateTime Expire { get ; set ; } private static readonly Dictionary< string , GuidToken> tokenCache = new Dictionary< string , GuidToken>(); public static ( bool , GuidToken) Valid( string token) { if ( string .IsNullOrEmpty(token) || token.Length != TOKEN_LENGTH) { return ( false , null ); } // 从 Session 中获取令牌实体 GuidToken tokenEntity = GetTokenCache(); if (tokenEntity == null ) { return ( false , null ); } else { tokenEntity.Expire = DateTime.Now.AddMinutes(expireDuration); } return ( true , tokenEntity); GuidToken GetTokenCache() { if (tokenCache.TryGetValue(token, out var val)) { if (val.Expire > DateTime.Now) return val; else tokenCache.Remove(token); } return null ; } } public static string Create( string openId = DEFAULT_OPENID, string role = DEFAULT_ROLE, int minutes = 30) { var token = Guid.NewGuid().ToString( "N" ); expireDuration = minutes; var entity = new GuidToken { OpenId = openId, Role = role, Expire = DateTime.Now.AddMinutes(expireDuration) }; tokenCache.Add(token, entity); return token; } /// <summary> /// 令牌实体 转 ClaimsPrincipal /// </summary> /// <param name="token"></param> /// <returns></returns> public ClaimsPrincipal ToClaimsPrincipal() { var claimsIdentity = new ClaimsIdentity( new Claim[] { new Claim(ClaimTypes.Name, OpenId), new Claim(ClaimTypes.Role, Role), }, GuidToken.DEFAULT_AUTHENTICATION_TYPE); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); return claimsPrincipal; } } |
最后就是使用方式
在 Startup 中配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public void ConfigureServices(IServiceCollection services) { // 注册使用 services.AddAuthentication(options => { options.AddScheme<HeaderAuth>(GuidToken.GUID_TOKEN_NAME, "Default Guid Token" ); options.DefaultAuthenticateScheme = GuidToken.GUID_TOKEN_NAME; options.DefaultChallengeScheme = GuidToken.GUID_TOKEN_NAME; }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors( "any" ); app.UseStaticFiles(); // 开启认证 app.UseAuthentication(); app.UseRouting(); // 开启授权 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } |
在控制器中使用标签
1
2
|
[Authorize] public class JobController : ControllerBase {} |
以上就是Asp.Net Core添加请求头自定义认证的示例的详细内容,更多关于Asp.Net Core添加请求头认证的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/marvelTitile/p/14636552.html