98 lines
3.6 KiB
C#
98 lines
3.6 KiB
C#
using System;
|
|
using System.Security.Claims;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.IdentityModel.Clients.ActiveDirectory;
|
|
|
|
namespace OpenIdConnect.AzureAdSample
|
|
{
|
|
public class AuthPropertiesTokenCache : TokenCache
|
|
{
|
|
private const string TokenCacheKey = ".TokenCache";
|
|
|
|
private HttpContext _httpContext;
|
|
private ClaimsPrincipal _principal;
|
|
private AuthenticationProperties _authProperties;
|
|
private string _signInScheme;
|
|
|
|
private AuthPropertiesTokenCache(AuthenticationProperties authProperties) : base()
|
|
{
|
|
_authProperties = authProperties;
|
|
BeforeAccess = BeforeAccessNotificationWithProperties;
|
|
AfterAccess = AfterAccessNotificationWithProperties;
|
|
BeforeWrite = BeforeWriteNotification;
|
|
}
|
|
|
|
private AuthPropertiesTokenCache(HttpContext httpContext, string signInScheme) : base()
|
|
{
|
|
_httpContext = httpContext;
|
|
_signInScheme = signInScheme;
|
|
BeforeAccess = BeforeAccessNotificationWithContext;
|
|
AfterAccess = AfterAccessNotificationWithContext;
|
|
BeforeWrite = BeforeWriteNotification;
|
|
}
|
|
|
|
public static TokenCache ForCodeRedemption(AuthenticationProperties authProperties)
|
|
{
|
|
return new AuthPropertiesTokenCache(authProperties);
|
|
}
|
|
|
|
public static TokenCache ForApiCalls(HttpContext httpContext,
|
|
string signInScheme = CookieAuthenticationDefaults.AuthenticationScheme)
|
|
{
|
|
return new AuthPropertiesTokenCache(httpContext, signInScheme);
|
|
}
|
|
|
|
private void BeforeAccessNotificationWithProperties(TokenCacheNotificationArgs args)
|
|
{
|
|
string cachedTokensText;
|
|
if (_authProperties.Items.TryGetValue(TokenCacheKey, out cachedTokensText))
|
|
{
|
|
var cachedTokens = Convert.FromBase64String(cachedTokensText);
|
|
Deserialize(cachedTokens);
|
|
}
|
|
}
|
|
|
|
private void BeforeAccessNotificationWithContext(TokenCacheNotificationArgs args)
|
|
{
|
|
// Retrieve the auth session with the cached tokens
|
|
var result = _httpContext.AuthenticateAsync(_signInScheme).Result;
|
|
_authProperties = result.Ticket.Properties;
|
|
_principal = result.Ticket.Principal;
|
|
|
|
BeforeAccessNotificationWithProperties(args);
|
|
}
|
|
|
|
private void AfterAccessNotificationWithProperties(TokenCacheNotificationArgs args)
|
|
{
|
|
// if state changed
|
|
if (HasStateChanged)
|
|
{
|
|
var cachedTokens = Serialize();
|
|
var cachedTokensText = Convert.ToBase64String(cachedTokens);
|
|
_authProperties.Items[TokenCacheKey] = cachedTokensText;
|
|
}
|
|
}
|
|
|
|
private void AfterAccessNotificationWithContext(TokenCacheNotificationArgs args)
|
|
{
|
|
// if state changed
|
|
if (HasStateChanged)
|
|
{
|
|
AfterAccessNotificationWithProperties(args);
|
|
|
|
var cachedTokens = Serialize();
|
|
var cachedTokensText = Convert.ToBase64String(cachedTokens);
|
|
_authProperties.Items[TokenCacheKey] = cachedTokensText;
|
|
_httpContext.SignInAsync(_signInScheme, _principal, _authProperties).Wait();
|
|
}
|
|
}
|
|
|
|
private void BeforeWriteNotification(TokenCacheNotificationArgs args)
|
|
{
|
|
// if you want to ensure that no concurrent write take place, use this notification to place a lock on the entry
|
|
}
|
|
}
|
|
}
|