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 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 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(); 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; } } }