Integrer l'authentification Keycloak dans l'application
This commit is contained in:
101
ChessCubing.App/Services/AppAuthenticationStateProvider.cs
Normal file
101
ChessCubing.App/Services/AppAuthenticationStateProvider.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.Net.Http.Json;
|
||||
using System.Security.Claims;
|
||||
using ChessCubing.App.Models.Auth;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
|
||||
namespace ChessCubing.App.Services;
|
||||
|
||||
public sealed class AppAuthenticationStateProvider(HttpClient httpClient) : AuthenticationStateProvider
|
||||
{
|
||||
private static readonly AuthenticationState AnonymousState = new(new ClaimsPrincipal(new ClaimsIdentity()));
|
||||
|
||||
private AuthenticationState? _cachedState;
|
||||
|
||||
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
||||
{
|
||||
if (_cachedState is not null)
|
||||
{
|
||||
return _cachedState;
|
||||
}
|
||||
|
||||
_cachedState = await LoadStateAsync();
|
||||
return _cachedState;
|
||||
}
|
||||
|
||||
public async Task RefreshAsync()
|
||||
{
|
||||
_cachedState = await LoadStateAsync();
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(_cachedState));
|
||||
}
|
||||
|
||||
public void SetAuthenticated(AuthSessionResponse session)
|
||||
{
|
||||
_cachedState = new AuthenticationState(BuildPrincipal(session));
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(_cachedState));
|
||||
}
|
||||
|
||||
public void SetAnonymous()
|
||||
{
|
||||
_cachedState = AnonymousState;
|
||||
NotifyAuthenticationStateChanged(Task.FromResult(_cachedState));
|
||||
}
|
||||
|
||||
private async Task<AuthenticationState> LoadStateAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var session = await httpClient.GetFromJsonAsync<AuthSessionResponse>("api/auth/session");
|
||||
if (session is null || !session.IsAuthenticated)
|
||||
{
|
||||
return AnonymousState;
|
||||
}
|
||||
|
||||
return new AuthenticationState(BuildPrincipal(session));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return AnonymousState;
|
||||
}
|
||||
}
|
||||
|
||||
private static ClaimsPrincipal BuildPrincipal(AuthSessionResponse session)
|
||||
{
|
||||
if (!session.IsAuthenticated)
|
||||
{
|
||||
return AnonymousState.User;
|
||||
}
|
||||
|
||||
var claims = new List<Claim>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(session.Subject))
|
||||
{
|
||||
claims.Add(new Claim("sub", session.Subject));
|
||||
claims.Add(new Claim(ClaimTypes.NameIdentifier, session.Subject));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(session.Username))
|
||||
{
|
||||
claims.Add(new Claim("preferred_username", session.Username));
|
||||
claims.Add(new Claim(ClaimTypes.Name, session.Username));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(session.Name))
|
||||
{
|
||||
claims.Add(new Claim("name", session.Name));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(session.Email))
|
||||
{
|
||||
claims.Add(new Claim("email", session.Email));
|
||||
claims.Add(new Claim(ClaimTypes.Email, session.Email));
|
||||
}
|
||||
|
||||
foreach (var role in session.Roles.Where(role => !string.IsNullOrWhiteSpace(role)))
|
||||
{
|
||||
claims.Add(new Claim("role", role));
|
||||
claims.Add(new Claim(ClaimTypes.Role, role));
|
||||
}
|
||||
|
||||
return new ClaimsPrincipal(new ClaimsIdentity(claims, "ChessCubingCookie"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user