前言
小项目中需要添加 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