-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Admin UI apikey authentication (#194)
* feat: add api key authentication to API * chore: remove unused classes * refactor: move ApiKeyAuthenticationSchemeHandler and extract constant for api key header name * feat: add ApiKeyValidator * refactor: move ApiKeyAuthenticationSchemeHandler to "Authentication" folder * feat: add ValidateApiKey endpoint * feat: added login component * feat: added auth service, guards and interceptor to manage authentication * fix: generated client id should be assigned instead of empty one * feat: add logout behavior and manage navigation based on authentication status * chore: pin OpenIddict to 4.3.0 * feat: validate api key on login attempt * feat: dismiss message on route change --------- Co-authored-by: Timo Notheisen <[email protected]>
- Loading branch information
1 parent
44bd5ad
commit 3d1f663
Showing
46 changed files
with
580 additions
and
176 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
AdminUi/src/AdminUi/Authentication/ApiKeyAuthenticationSchemeHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System.Security.Claims; | ||
using System.Text.Encodings.Web; | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace AdminUi.AspNet; | ||
|
||
public class ApiKeyAuthenticationSchemeOptions : AuthenticationSchemeOptions | ||
{ | ||
public string ApiKey { get; set; } = string.Empty; | ||
} | ||
|
||
public class ApiKeyAuthenticationSchemeHandler : AuthenticationHandler<ApiKeyAuthenticationSchemeOptions> | ||
{ | ||
private readonly ApiKeyValidator _apiKeyValidator; | ||
private const string API_KEY_HEADER_NAME = "X-API-KEY"; | ||
|
||
public ApiKeyAuthenticationSchemeHandler(IOptionsMonitor<ApiKeyAuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, ApiKeyValidator apiKeyValidator) : base(options, logger, encoder, clock) | ||
{ | ||
_apiKeyValidator = apiKeyValidator; | ||
} | ||
|
||
protected override Task<AuthenticateResult> HandleAuthenticateAsync() | ||
{ | ||
var apiKey = Context.Request.Headers[API_KEY_HEADER_NAME]; | ||
|
||
if (!_apiKeyValidator.IsApiKeyValid(apiKey)) | ||
{ | ||
return Task.FromResult(AuthenticateResult.Fail($"Invalid {API_KEY_HEADER_NAME}")); | ||
} | ||
var claims = new[] { new Claim(ClaimTypes.Name, "VALID USER") }; | ||
var identity = new ClaimsIdentity(claims, Scheme.Name); | ||
var principal = new ClaimsPrincipal(identity); | ||
var ticket = new AuthenticationTicket(principal, Scheme.Name); | ||
return Task.FromResult(AuthenticateResult.Success(ticket)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace AdminUi.AspNet; | ||
|
||
public class ApiKeyValidator | ||
{ | ||
private readonly ApiKeyAuthenticationSchemeOptions _options; | ||
|
||
public ApiKeyValidator(IOptionsMonitor<ApiKeyAuthenticationSchemeOptions> options) | ||
{ | ||
_options = options.Get("ApiKey"); | ||
} | ||
|
||
public bool IsApiKeyValid(string? apiKey) | ||
{ | ||
var apiKeyIsConfigured = !string.IsNullOrEmpty(_options.ApiKey); | ||
|
||
if (!apiKeyIsConfigured) return true; | ||
|
||
return apiKey == _options.ApiKey; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,9 @@ | |
.layout-content { | ||
padding: 1rem; | ||
} | ||
|
||
.login-layout { | ||
display: flex; | ||
justify-content: center; | ||
background: #673ab7; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,16 @@ | ||
<div class="layout-wrapper"> | ||
<app-topbar></app-topbar> | ||
<mat-sidenav-container (backdropClick)="closeSidebar()" autosize> | ||
<mat-sidenav | ||
#sidebar | ||
[opened]="isSidebarOpen()" | ||
[mode]="isMobile() ? 'over' : 'side'" | ||
> | ||
<div class="layout-wrapper" [ngClass]="{'login-layout': (isLoggedIn$ | async) === false}"> | ||
<app-topbar *ngIf="isLoggedIn$ | async"></app-topbar> | ||
<mat-sidenav-container *ngIf="isLoggedIn$ | async" (backdropClick)="closeSidebar()" autosize> | ||
<mat-sidenav #sidebar [opened]="isSidebarOpen()" [mode]="isMobile() ? 'over' : 'side'"> | ||
<app-sidebar></app-sidebar> | ||
</mat-sidenav> | ||
<mat-sidenav-content class="layout-main-container"> | ||
<div class="layout-content"> | ||
<router-outlet></router-outlet> | ||
<router-outlet (activate)="changeOfRoute()"></router-outlet> | ||
</div> | ||
</mat-sidenav-content> | ||
</mat-sidenav-container> | ||
</div> | ||
<div *ngIf="(isLoggedIn$ | async) === false"> | ||
<router-outlet></router-outlet> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.