AuthorizationServerDemos/CSharp/TaxApp/BearerTokenHandler.cs
2021-01-18 18:32:22 +03:00

104 lines
4.1 KiB
C#

using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace OidcSamples.TaxApp
{
public class BearerTokenHandler : DelegatingHandler
{
private readonly IHttpContextAccessor httpContextAccessor;
private readonly IHttpClientFactory httpClientFactory;
public BearerTokenHandler(
IHttpContextAccessor httpContextAccessor,
IHttpClientFactory httpClientFactory)
{
this.httpContextAccessor = httpContextAccessor;
this.httpClientFactory = httpClientFactory;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var accessToken = await GetAccessTokenAsync();
if (accessToken != null)
{
request.SetBearerToken(accessToken);
// request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
}
return await base.SendAsync(request, cancellationToken);
}
public async Task<string> GetAccessTokenAsync()
{
var expiresAt = await httpContextAccessor.HttpContext.GetTokenAsync("expires_at");
var expiresAtAsDateTimeOffset = DateTimeOffset.Parse(expiresAt, CultureInfo.InvariantCulture);
if (expiresAtAsDateTimeOffset.AddSeconds(-60).ToUniversalTime() > DateTime.UtcNow)
{
// no need to refresh, return access token
return await httpContextAccessor.HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);
}
var idpClient = httpClientFactory.CreateClient("IDPClient");
var discoveryResponse = await idpClient.GetDiscoveryDocumentAsync();
var refreshToken = await httpContextAccessor.HttpContext.GetTokenAsync(OpenIdConnectParameterNames.RefreshToken);
var refreshResponse = await idpClient.RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = discoveryResponse.TokenEndpoint,
ClientId = "b4f24c7bc65b4621bba91e13e9066047",
ClientSecret = "ef3d771aaebf43b691dc8e69a75d67ea",
RefreshToken = refreshToken
});
if (refreshResponse.IsError)
{
return null;
}
var updatedTokens = new List<AuthenticationToken>();
updatedTokens.Add(new AuthenticationToken
{
Name = OpenIdConnectParameterNames.IdToken,
Value = refreshResponse.IdentityToken
});
updatedTokens.Add(new AuthenticationToken
{
Name = OpenIdConnectParameterNames.AccessToken,
Value = refreshResponse.AccessToken
});
updatedTokens.Add(new AuthenticationToken
{
Name = OpenIdConnectParameterNames.RefreshToken,
Value = refreshResponse.RefreshToken
});
updatedTokens.Add(new AuthenticationToken
{
Name = "expires_at",
Value = (DateTime.UtcNow + TimeSpan.FromSeconds(refreshResponse.ExpiresIn))
.ToString("O", CultureInfo.InvariantCulture)
});
var currentAuthenticationResult = await httpContextAccessor.HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
currentAuthenticationResult.Properties.StoreTokens(updatedTokens);
await httpContextAccessor.HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
currentAuthenticationResult.Principal,
currentAuthenticationResult.Properties);
return refreshResponse.AccessToken;
}
}
}