finished OpenID integration
This commit is contained in:
@@ -38,7 +38,7 @@ public class HopFrameAuthentication(
|
||||
|
||||
var tokenEntry = await tokens.GetToken(accessToken);
|
||||
|
||||
if (tokenEntry?.Type != Token.ApiTokenType && openIdOptions.Value.Enabled) {
|
||||
if (tokenEntry?.Type != Token.ApiTokenType && openIdOptions.Value.Enabled && !Guid.TryParse(accessToken, out _)) {
|
||||
var result = await accessor.InspectToken(accessToken);
|
||||
|
||||
if (result is null || !result.Active)
|
||||
@@ -65,10 +65,13 @@ public class HopFrameAuthentication(
|
||||
CreatedAt = DateTime.Now,
|
||||
Type = Token.OpenIdTokenType
|
||||
};
|
||||
var identity = await GenerateClaims(token);
|
||||
var identity = await GenerateClaims(token, perms);
|
||||
return AuthenticateResult.Success(new AuthenticationTicket(identity, Scheme.Name));
|
||||
}
|
||||
|
||||
if (!tokenOptions.Value.DefaultAuthentication)
|
||||
return AuthenticateResult.Fail("HopFrame authentication scheme is disabled");
|
||||
|
||||
if (tokenEntry is null) return AuthenticateResult.Fail("The provided Access Token does not exist");
|
||||
|
||||
if (tokenEntry.Type == Token.ApiTokenType) {
|
||||
@@ -78,11 +81,11 @@ public class HopFrameAuthentication(
|
||||
if (tokenEntry.Owner is null)
|
||||
return AuthenticateResult.Fail("The provided Access Token does not match any user");
|
||||
|
||||
var principal = await GenerateClaims(tokenEntry);
|
||||
var principal = await GenerateClaims(tokenEntry, perms);
|
||||
return AuthenticateResult.Success(new AuthenticationTicket(principal, Scheme.Name));
|
||||
}
|
||||
|
||||
private async Task<ClaimsPrincipal> GenerateClaims(Token token) {
|
||||
public static async Task<ClaimsPrincipal> GenerateClaims(Token token, IPermissionRepository perms) {
|
||||
var claims = new List<Claim> {
|
||||
new(HopFrameClaimTypes.AccessTokenId, token.TokenId.ToString()),
|
||||
new(HopFrameClaimTypes.UserId, token.Owner.Id.ToString())
|
||||
|
||||
@@ -8,6 +8,8 @@ public class HopFrameAuthenticationOptions : OptionsFromConfiguration {
|
||||
public TimeSpan AccessTokenTime => AccessToken is null ? new(0, 0, 5, 0) : AccessToken.ConstructTimeSpan;
|
||||
public TimeSpan RefreshTokenTime => RefreshToken is null ? new(30, 0, 0, 0) : RefreshToken.ConstructTimeSpan;
|
||||
|
||||
public bool DefaultAuthentication { get; set; } = true;
|
||||
|
||||
public TokenTime AccessToken { get; set; }
|
||||
public TokenTime RefreshToken { get; set; }
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace HopFrame.Security.Authentication.OpenID;
|
||||
|
||||
public interface IOpenIdAccessor {
|
||||
Task<OpenIdConfiguration> LoadConfiguration();
|
||||
Task<OpenIdToken> RequestToken(string code);
|
||||
Task<string> ConstructAuthUri(string state = null);
|
||||
Task<OpenIdToken> RequestToken(string code, string defaultCallback);
|
||||
Task<string> ConstructAuthUri(string defaultCallback, string state = null);
|
||||
Task<OpenIdIntrospection> InspectToken(string token);
|
||||
Task<OpenIdToken> RefreshAccessToken(string refreshToken);
|
||||
}
|
||||
@@ -8,8 +8,6 @@ using Microsoft.Extensions.Options;
|
||||
namespace HopFrame.Security.Authentication.OpenID.Implementation;
|
||||
|
||||
internal class OpenIdAccessor(IHttpClientFactory clientFactory, IOptions<OpenIdOptions> options, IHttpContextAccessor accessor, IMemoryCache cache) : IOpenIdAccessor {
|
||||
private const string DefaultCallbackEndpoint = "api/v1/openid/callback";
|
||||
|
||||
private const string ConfigurationCacheKey = "HopFrame:OpenID:Configuration";
|
||||
private const string AuthCodeCacheKey = "HopFrame:OpenID:Code:";
|
||||
private const string TokenCacheKey = "HopFrame:OpenID:Token:";
|
||||
@@ -34,13 +32,13 @@ internal class OpenIdAccessor(IHttpClientFactory clientFactory, IOptions<OpenIdO
|
||||
return config;
|
||||
}
|
||||
|
||||
public async Task<OpenIdToken> RequestToken(string code) {
|
||||
public async Task<OpenIdToken> RequestToken(string code, string defaultCallback) {
|
||||
if (options.Value.Cache.Enabled && options.Value.Cache.Auth.Enabled && cache.TryGetValue(AuthCodeCacheKey + code, out object cachedToken)) {
|
||||
return cachedToken as OpenIdToken;
|
||||
}
|
||||
|
||||
var protocol = accessor.HttpContext!.Request.IsHttps ? "https" : "http";
|
||||
var callback = options.Value.Callback ?? $"{protocol}://{accessor.HttpContext!.Request.Host.Value}/{DefaultCallbackEndpoint}";
|
||||
var callback = options.Value.Callback ?? $"{protocol}://{accessor.HttpContext!.Request.Host.Value}/{defaultCallback}";
|
||||
|
||||
var configuration = await LoadConfiguration();
|
||||
|
||||
@@ -67,9 +65,9 @@ internal class OpenIdAccessor(IHttpClientFactory clientFactory, IOptions<OpenIdO
|
||||
return token;
|
||||
}
|
||||
|
||||
public async Task<string> ConstructAuthUri(string state = null) {
|
||||
public async Task<string> ConstructAuthUri(string defaultCallback, string state = null) {
|
||||
var protocol = accessor.HttpContext!.Request.IsHttps ? "https" : "http";
|
||||
var callback = options.Value.Callback ?? $"{protocol}://{accessor.HttpContext!.Request.Host.Value}/{DefaultCallbackEndpoint}";
|
||||
var callback = options.Value.Callback ?? $"{protocol}://{accessor.HttpContext!.Request.Host.Value}/{defaultCallback}";
|
||||
|
||||
var configuration = await LoadConfiguration();
|
||||
return $"{configuration.AuthorizationEndpoint}?response_type=code&client_id={options.Value.ClientId}&redirect_uri={callback}&scope=openid%20profile%20email%20offline_access&state={state}";
|
||||
|
||||
Reference in New Issue
Block a user