我想在使用 Windows.Web.Http 的 UWP 应用程序中使用为 System.Net.Http 添加的 IdentityModel 扩展方法 (TokenRefresh)。但是,我目前使用的是 4.3.1 版本。在此版本上,Windows.Web.Http.HttpClient 扩展不可用。
Nuget: Install-Package IdentityModel -Version 4.3.1
我想在使用 Windows.Web.Http 的 UWP 应用程序中使用为 System.Net.Http 添加的 IdentityModel 扩展方法 (TokenRefresh)。但是,我目前使用的是 4.3.1 版本。在此版本上,Windows.Web.Http.HttpClient 扩展不可用。
Nuget: Install-Package IdentityModel -Version 4.3.1
IdentityModel 的创建者拒绝添加对该Windows.Web.Http
模块的支持。所以我自己实现了刷新令牌。欢迎您在这里指出任何问题。
public static async Task<HttpClient> GetHttpClient()
{
var httpBaseProtocolFilter = new HttpBaseProtocolFilter
{
MaxVersion = HttpVersion.Http20,
};
return await SetHeaders(new HttpClient(httpBaseProtocolFilter));
}
private static async Task<HttpClient> SetHeaders(HttpClient httpClient)
{
try
{
httpClient.DefaultRequestHeaders.Add("X-requestIp", DeviceIp);
httpClient.DefaultRequestHeaders.Add("client", "5");
if (OAuth2Manager.Token != null && !string.IsNullOrWhiteSpace(OAuth2Manager.Token.AccessToken))
httpClient.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", OAuth2Manager.Token.AccessToken));
return httpClient;
}
catch (Exception)
{
throw;
}
}
private static async Task<ResponseDataModel> RequestSender1(object postData, string requestUrl,
string requestMehtod, Action<HttpProgress> OnSendRequestProgress)
{
try
{
HttpClient httpClient = await GetHttpClient();
httpClient = await SetBearerToken(httpClient);
//Do all the request send related stuff here
}
catch (Exception)
{
}
}
static readonly SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
private static async Task<HttpClient> SetBearerToken(HttpClient httpClient)
{
try
{
if (OAuth2Manager.TokenExpiration < DateTime.Now)
{
await semaphoreSlim.WaitAsync();
try
{
await OAuth2Manager.RequestRefreshTokenAsync();
}
finally
{
semaphoreSlim.Release();
}
}
return httpClient;
}
catch (Exception)
{
throw;
}
}
//retryCount = 3
//tempRetryCount = 1
public static async Task<TokenResponse> RequestRefreshTokenAsync()
{
try
{
do
{
if (retryCount == tempRetryCount) break;
Token = await RequestRefreshTokenAsyncInternal();
tempRetryCount++;
if (Token.IsError || !string.IsNullOrWhiteSpace(Token.Error))
{
//Log errors
}
} while (Token.IsError || !string.IsNullOrWhiteSpace(Token.Error));
if (Token.IsError || !string.IsNullOrWhiteSpace(Token.Error))
{
//Log errors
return Token;
}
//percentage == 80
//Token expiration set as 80% of the actual expire value so 20% of the remaining time can be
//used to send a refresh token request.
TokenExpiration = DateTime.Now.AddSeconds(Token.ExpiresIn * percentage / 100);
return Token;
}
catch (Exception)
{
throw;
}
}
private static async Task<TokenResponse> RequestRefreshTokenAsyncInternal()
{
try
{
if (Token == null || Token.RefreshToken != null)
{
Token = await httpClient.RequestRefreshTokenAsync(new RefreshTokenRequest()
{
Address = discoveryDocumentResponse.TokenEndpoint,
RefreshToken = Token.RefreshToken,
ClientId = clientId,
ClientSecret = clientSecret,
AuthorizationHeaderStyle = BasicAuthenticationHeaderStyle.Rfc6749,
});
if (Token.IsError && Token.HttpStatusCode == System.Net.HttpStatusCode.BadRequest && Token.Error.Equals(ApplicationConstants.InvalidGrant))
{
await RequestPasswordTokenAsync(Global.Username, Global.Password);
}
}
else
{
await RequestPasswordTokenAsync(Global.Username, Global.Password);
}
if (Token.IsError || !string.IsNullOrWhiteSpace(Token.Error))
{
//Log errors
}
return Token;
}
catch (Exception)
{
throw;
}
}
希望你能明白我做了什么。干杯!