89 lines
2.7 KiB
C#
89 lines
2.7 KiB
C#
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.Identity.Web;
|
|
using Shogi.Api.Extensions;
|
|
using Shogi.Api.Models;
|
|
using Shogi.Api.Repositories;
|
|
using System.Security.Claims;
|
|
|
|
namespace Shogi.Api;
|
|
|
|
/// <summary>
|
|
/// Standardizes the claims from third party issuers. Also registers new msal users in the database.
|
|
/// </summary>
|
|
public class ShogiUserClaimsTransformer : IShogiUserClaimsTransformer
|
|
{
|
|
private readonly IUserRepository userRepository;
|
|
|
|
public ShogiUserClaimsTransformer(IUserRepository userRepository)
|
|
{
|
|
this.userRepository = userRepository;
|
|
}
|
|
|
|
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
|
|
{
|
|
var newPrincipal = principal.IsMicrosoft()
|
|
? await CreateClaimsFromMicrosoftPrincipal(principal)
|
|
: await CreateClaimsFromGuestPrincipal(principal);
|
|
|
|
return newPrincipal;
|
|
}
|
|
|
|
public async Task<ClaimsPrincipal> CreateClaimsFromGuestPrincipal(ClaimsPrincipal principal)
|
|
{
|
|
var id = principal.GetGuestUserId();
|
|
if (string.IsNullOrWhiteSpace(id))
|
|
{
|
|
var newUser = User.CreateGuestUser(Guid.NewGuid().ToString());
|
|
await this.userRepository.CreateUser(newUser);
|
|
return new ClaimsPrincipal(CreateClaimsIdentity(newUser));
|
|
}
|
|
|
|
var user = await this.userRepository.ReadUser(id);
|
|
if (user == null) throw new UnauthorizedAccessException("Guest account does not exist.");
|
|
return new ClaimsPrincipal(CreateClaimsIdentity(user));
|
|
}
|
|
|
|
private async Task<ClaimsPrincipal> CreateClaimsFromMicrosoftPrincipal(ClaimsPrincipal principal)
|
|
{
|
|
var id = principal.GetMicrosoftUserId();
|
|
if (string.IsNullOrWhiteSpace(id))
|
|
{
|
|
throw new UnauthorizedAccessException("Found MSAL claims but no preferred_username.");
|
|
}
|
|
|
|
var user = await this.userRepository.ReadUser(id);
|
|
if (user == null)
|
|
{
|
|
user = User.CreateMsalUser(id);
|
|
await this.userRepository.CreateUser(user);
|
|
}
|
|
return new ClaimsPrincipal(CreateClaimsIdentity(user));
|
|
|
|
}
|
|
|
|
private static ClaimsIdentity CreateClaimsIdentity(User user)
|
|
{
|
|
var claims = new List<Claim>(4)
|
|
{
|
|
new Claim(ClaimTypes.NameIdentifier, user.Id),
|
|
new Claim(ClaimTypes.Name, user.DisplayName),
|
|
};
|
|
if (user.LoginPlatform == WhichLoginPlatform.Guest)
|
|
{
|
|
|
|
claims.Add(new Claim(ClaimTypes.Role, "Guest"));
|
|
return new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
|
}
|
|
else
|
|
{
|
|
return new ClaimsIdentity(claims, JwtBearerDefaults.AuthenticationScheme);
|
|
}
|
|
}
|
|
}
|
|
|
|
public interface IShogiUserClaimsTransformer : IClaimsTransformation
|
|
{
|
|
Task<ClaimsPrincipal> CreateClaimsFromGuestPrincipal(ClaimsPrincipal principal);
|
|
} |