OIDC improvements

This commit is contained in:
Shaun Walker
2022-03-21 09:12:18 -04:00
parent 1a86b80c61
commit 4b19059df1
7 changed files with 29 additions and 255 deletions

View File

@ -1,112 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
namespace Oqtane.Infrastructure
{
internal class SiteAuthenticationSchemeProvider : IAuthenticationSchemeProvider
{
public SiteAuthenticationSchemeProvider(IOptions<AuthenticationOptions> options)
: this(options, new Dictionary<string, AuthenticationScheme>(StringComparer.Ordinal))
{
}
public SiteAuthenticationSchemeProvider(IOptions<AuthenticationOptions> options, IDictionary<string, AuthenticationScheme> schemes)
{
_optionsProvider = options;
_schemes = schemes ?? throw new ArgumentNullException(nameof(schemes));
_requestHandlers = new List<AuthenticationScheme>();
foreach (var builder in _optionsProvider.Value.Schemes)
{
var scheme = builder.Build();
AddScheme(scheme);
}
}
private readonly IOptions<AuthenticationOptions> _optionsProvider;
private readonly object _lock = new object();
private readonly IDictionary<string, AuthenticationScheme> _schemes;
private readonly List<AuthenticationScheme> _requestHandlers;
private Task<AuthenticationScheme> GetDefaultSchemeAsync()
=> _optionsProvider.Value.DefaultScheme != null
? GetSchemeAsync(_optionsProvider.Value.DefaultScheme)
: Task.FromResult<AuthenticationScheme>(null);
public virtual Task<AuthenticationScheme> GetDefaultAuthenticateSchemeAsync()
=> _optionsProvider.Value.DefaultAuthenticateScheme != null
? GetSchemeAsync(_optionsProvider.Value.DefaultAuthenticateScheme)
: GetDefaultSchemeAsync();
public virtual Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync()
=> _optionsProvider.Value.DefaultChallengeScheme != null
? GetSchemeAsync(_optionsProvider.Value.DefaultChallengeScheme)
: GetDefaultSchemeAsync();
public virtual Task<AuthenticationScheme> GetDefaultForbidSchemeAsync()
=> _optionsProvider.Value.DefaultForbidScheme != null
? GetSchemeAsync(_optionsProvider.Value.DefaultForbidScheme)
: GetDefaultChallengeSchemeAsync();
public virtual Task<AuthenticationScheme> GetDefaultSignInSchemeAsync()
=> _optionsProvider.Value.DefaultSignInScheme != null
? GetSchemeAsync(_optionsProvider.Value.DefaultSignInScheme)
: GetDefaultSchemeAsync();
public virtual Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync()
=> _optionsProvider.Value.DefaultSignOutScheme != null
? GetSchemeAsync(_optionsProvider.Value.DefaultSignOutScheme)
: GetDefaultSignInSchemeAsync();
public virtual Task<AuthenticationScheme> GetSchemeAsync(string name)
=> Task.FromResult(_schemes.ContainsKey(name) ? _schemes[name] : null);
public virtual Task<IEnumerable<AuthenticationScheme>> GetRequestHandlerSchemesAsync()
=> Task.FromResult<IEnumerable<AuthenticationScheme>>(_requestHandlers);
public virtual void AddScheme(AuthenticationScheme scheme)
{
if (_schemes.ContainsKey(scheme.Name))
{
throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
}
lock (_lock)
{
if (_schemes.ContainsKey(scheme.Name))
{
throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
}
if (typeof(IAuthenticationRequestHandler).IsAssignableFrom(scheme.HandlerType))
{
_requestHandlers.Add(scheme);
}
_schemes[scheme.Name] = scheme;
}
}
public virtual void RemoveScheme(string name)
{
if (!_schemes.ContainsKey(name))
{
return;
}
lock (_lock)
{
if (_schemes.ContainsKey(name))
{
var scheme = _schemes[name];
_requestHandlers.Remove(scheme);
_schemes.Remove(name);
}
}
}
public virtual Task<IEnumerable<AuthenticationScheme>> GetAllSchemesAsync()
=> Task.FromResult<IEnumerable<AuthenticationScheme>>(_schemes.Values);
}
}

View File

@ -1,62 +0,0 @@
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Oqtane.Extensions;
using Oqtane.Models;
using Oqtane.Shared;
namespace Oqtane.Infrastructure
{
internal class SiteAuthenticationService<TAlias> : IAuthenticationService
where TAlias : class, IAlias, new()
{
private readonly IAuthenticationService _inner;
public SiteAuthenticationService(IAuthenticationService inner)
{
_inner = inner ?? throw new System.ArgumentNullException(nameof(inner));
}
private static void AddTenantIdentifierToProperties(HttpContext context, ref AuthenticationProperties properties)
{
// add site identifier to the authentication properties so on the callback we can use it to set context
var alias = context.GetAlias();
if (alias != null)
{
properties ??= new AuthenticationProperties();
if (!properties.Items.Keys.Contains(Constants.SiteToken))
{
properties.Items.Add(Constants.SiteToken, alias.SiteKey);
}
}
}
public Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme)
=> _inner.AuthenticateAsync(context, scheme);
public async Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)
{
AddTenantIdentifierToProperties(context, ref properties);
await _inner.ChallengeAsync(context, scheme, properties);
}
public async Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties)
{
AddTenantIdentifierToProperties(context, ref properties);
await _inner.ForbidAsync(context, scheme, properties);
}
public async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
{
AddTenantIdentifierToProperties(context, ref properties);
await _inner.SignInAsync(context, scheme, principal, properties);
}
public async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties)
{
AddTenantIdentifierToProperties(context, ref properties);
await _inner.SignOutAsync(context, scheme, properties);
}
}
}

View File

@ -33,7 +33,7 @@ namespace Oqtane.Infrastructure
alias.SiteSettings = cache.GetOrCreate("sitesettings:" + alias.SiteKey, entry =>
{
var settingRepository = context.RequestServices.GetService(typeof(ISettingRepository)) as ISettingRepository;
return settingRepository.GetSettings(EntityNames.Site)
return settingRepository.GetSettings(EntityNames.Site, alias.SiteId)
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
});
// save alias in HttpContext