问题描述
我想在使用 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 refused to add support 到 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;
}
}
希望你能理解我所做的。干杯!