-
Notifications
You must be signed in to change notification settings - Fork 451
Expand file tree
/
Copy pathDynamicTokenProvider.cs
More file actions
129 lines (113 loc) · 4.19 KB
/
Copy pathDynamicTokenProvider.cs
File metadata and controls
129 lines (113 loc) · 4.19 KB
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebApiClientCore.Extensions.OAuths.Exceptions;
namespace WebApiClientCore.Extensions.OAuths.TokenProviders
{
/// <summary>
/// 表示多应用下Token提供者抽象类
/// </summary>
public abstract class DynamicTokenProvider : IDynamicTokenProvider
{
/// <summary>
/// token缓存
/// </summary>
private static readonly ConcurrentDictionary<string, TokenResult> tokenResults
= new ConcurrentDictionary<string, TokenResult>();
/// <summary>
/// 服务提供者
/// </summary>
private readonly IServiceProvider _services;
/// <summary>
/// 异步锁
/// </summary>
private readonly AsyncRoot asyncRoot = new AsyncRoot();
/// <summary>
/// 获取或设置别名
/// </summary>
public string Name { get; set; } = Options.DefaultName;
/// <summary>
/// 表示多应用Token提供者抽象类
/// </summary>
protected DynamicTokenProvider(IServiceProvider service)
{
_services = service;
}
private const string _default_identifier = "default";
/// <summary>
/// 强制清除token以支持下次获取到新的token
/// </summary>
public void ClearToken()
{
ClearTokenAsync(_default_identifier).Wait();
}
/// <summary>
/// 强制清除token以支持下次获取到新的token
/// </summary>
/// <param name="identifier">应用标识</param>
public async Task ClearTokenAsync(string identifier)
{
using (await asyncRoot.LockAsync().ConfigureAwait(false))
{
identifier ??= _default_identifier;
if (tokenResults.ContainsKey(identifier))
tokenResults.Remove(identifier, out _);
}
}
/// <summary>
/// 根据应用标识获取token信息
/// </summary>
public async Task<TokenResult> GetTokenAsync(string identifier)
{
using (await asyncRoot.LockAsync().ConfigureAwait(false))
{
identifier ??= _default_identifier;
if (!tokenResults.TryGetValue(identifier, out var token) || token.IsExpired())
{
using var scope = _services.CreateScope();
token = (token?.CanRefresh() != true)
? await RequestTokenAsync(scope.ServiceProvider).ConfigureAwait(false)
: await RefreshTokenAsync(scope.ServiceProvider, token.Refresh_token!).ConfigureAwait(false);
if (token == null)
{
throw new TokenNullException();
}
tokenResults.AddOrUpdate(identifier, token, (key, old) => token);
return token.EnsureSuccess();
}
return token;
}
}
/// <summary>
/// 获取token信息
/// </summary>
public async Task<TokenResult> GetTokenAsync()
{
return await GetTokenAsync(_default_identifier).ConfigureAwait(false);
}
/// <summary>
/// 请求获取token
/// </summary>
/// <param name="serviceProvider">服务提供者</param>
/// <returns></returns>
protected abstract Task<TokenResult?> RequestTokenAsync(IServiceProvider serviceProvider);
/// <summary>
/// 刷新token
/// </summary>
/// <param name="serviceProvider">服务提供者</param>
/// <param name="refresh_token">刷新token</param>
/// <returns></returns>
protected abstract Task<TokenResult?> RefreshTokenAsync(IServiceProvider serviceProvider, string refresh_token);
/// <summary>
/// 转换为string
/// </summary>
/// <returns></returns>
public override string ToString()
{
return $"{Name}";
}
}
}