mirror of
https://github.com/ditkrg/AuthorizationServerDemos.git
synced 2026-01-22 21:46:58 +00:00
104 lines
4.1 KiB
C#
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;
|
|
}
|
|
}
|
|
} |