@@ -11,8 +11,22 @@ namespace {{packageName}}.Client.Auth
11
11
/// < summary>
12
12
/// An authenticator for OAuth2 authentication flows
13
13
/// < /summary>
14
- public class OAuthAuthenticator : AuthenticatorBase
14
+ public class OAuthAuthenticator : IAuthenticator
15
15
{
16
+ private TokenResponse{{nrt?} } _token;
17
+
18
+ public string{ {nrt?} } Token
19
+ {
20
+ get
21
+ {
22
+ if (_token == null) return null;
23
+ if (_token.ExpiresIn == null) return _token.AccessToken;
24
+ if (_token.ExpiresAt < DateTime.Now) return null;
25
+
26
+ return _token.AccessToken;
27
+ }
28
+ }
29
+
16
30
readonly string _tokenUrl;
17
31
readonly string _clientId;
18
32
readonly string _clientSecret;
@@ -31,7 +45,7 @@ namespace {{packageName}}.Client.Auth
31
45
string{ {nrt?} } scope,
32
46
OAuthFlow? flow,
33
47
JsonSerializerSettings serializerSettings,
34
- IReadableConfiguration configuration) : base("")
48
+ IReadableConfiguration configuration)
35
49
{
36
50
_tokenUrl = tokenUrl;
37
51
_clientId = clientId;
@@ -64,10 +78,10 @@ namespace {{packageName}}.Client.Auth
64
78
/// </summary >
65
79
/// <param name =" accessToken" >Access token to create a parameter from.</param >
66
80
/// <returns >An authentication parameter.</returns >
67
- protected override async ValueTask<Parameter > GetAuthenticationParameter(string accessToken )
81
+ protected async ValueTask<Parameter > GetAuthenticationParameter()
68
82
{
69
83
var token = string.IsNullOrEmpty(Token) ? await GetToken().ConfigureAwait(false ) : Token;
70
- return new HeaderParameter(KnownHeaders.Authorization, token);
84
+ return new HeaderParameter(KnownHeaders.Authorization, token! );
71
85
}
72
86
73
87
/// <summary >
@@ -76,31 +90,39 @@ namespace {{packageName}}.Client.Auth
76
90
/// <returns >An authentication token.</returns >
77
91
async Task<string > GetToken()
78
92
{
79
- var client = new RestClient(_tokenUrl,
80
- configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(_serializerSettings, _configuration)));
81
-
82
- var request = new RestRequest()
83
- .AddParameter(" grant_type" , _grantType)
84
- .AddParameter(" client_id" , _clientId)
85
- .AddParameter(" client_secret" , _clientSecret);
93
+ var client = new RestClient(_tokenUrl, configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(_serializerSettings, _configuration)));
86
94
95
+ var request = new RestRequest();
96
+ if (! string.IsNullOrWhiteSpace(_token?.RefreshToken))
97
+ {
98
+ request.AddParameter(" grant_type" , " refresh_token" )
99
+ .AddParameter(" refresh_token" , _token! .RefreshToken);
100
+ }
101
+ else
102
+ {
103
+ request
104
+ .AddParameter(" grant_type" , _grantType)
105
+ .AddParameter(" client_id" , _clientId)
106
+ .AddParameter(" client_secret" , _clientSecret);
107
+ }
87
108
if (!string.IsNullOrEmpty(_scope))
88
109
{
89
110
request.AddParameter(" scope" , _scope);
90
111
}
91
-
92
- var response = await client.PostAsync<TokenResponse >(request).ConfigureAwait(false);
93
-
112
+ _token = await client.PostAsync<TokenResponse >(request).ConfigureAwait(false);
94
113
// RFC6749 - token_type is case insensitive.
95
114
// RFC6750 - In Authorization header Bearer should be capitalized.
96
115
// Fix the capitalization irrespective of token_type casing.
97
- switch (response .TokenType?.ToLower())
116
+ switch (_token? .TokenType?.ToLower())
98
117
{
99
118
case " bearer" :
100
- return $" Bearer {response .AccessToken}" ;
119
+ return $" Bearer {_token .AccessToken}" ;
101
120
default :
102
- return $" {response .TokenType} {response .AccessToken}" ;
121
+ return $" {_token? .TokenType} {_token? .AccessToken}" ;
103
122
}
104
123
}
124
+
125
+ public async ValueTask Authenticate(IRestClient client, RestRequest request)
126
+ => request.AddOrUpdateParameter(await GetAuthenticationParameter().ConfigureAwait(false));
105
127
}
106
128
}
0 commit comments