Skip to content

Commit 0de7e1d

Browse files
committed
Temp save
1 parent 4e9ca6c commit 0de7e1d

File tree

3 files changed

+126
-8
lines changed

3 files changed

+126
-8
lines changed

src/Aliencube.Azure.Extensions.EasyAuth.Emulator/Components/Pages/EasyAuthLogin.razor

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@page "/.auth/login/{authenticationType}"
1+
@page "/.auth/login/{identityProvider}"
22
@inject IEasyAuthService EasyAuthService
33
@inject NavigationManager NavigationManager
44
@rendermode @(new InteractiveServerRenderMode(prerender: false))
@@ -12,7 +12,7 @@
1212
<div class="row mb-3">
1313
<label class="form-label col-2 text-end" for="authentication-type">Provider</label>
1414
<div class="col-10">
15-
<input type="text" class="form-control" id="authentication-type" placeholder="Choose an auth provider" value="@AuthenticationType" disabled>
15+
<input type="text" class="form-control" id="authentication-type" placeholder="Choose an auth provider" value="@IdentityProvider" disabled>
1616
<small class="form-text text-muted">Name of the identity provider</small>
1717
</div>
1818
</div>
@@ -70,29 +70,39 @@
7070
private string? UserClaims { get; set; }
7171

7272
[Parameter]
73-
public string? AuthenticationType { get; set; }
73+
public string? IdentityProvider { get; set; }
74+
75+
[CascadingParameter]
76+
private HttpContext? HttpContext { get; set; }
7477

7578
protected override async Task OnInitializedAsync()
7679
{
7780
this.UserId = this.EasyAuthService.UserId.ToString("N");
7881
this.Username = string.Empty;
7982
this.UserRoles = this.ParseUserRoles(this.EasyAuthService.UserRoles);
80-
this.UserClaims = this.ParseUserClaims(await this.EasyAuthService.GetUserClaims(this.AuthenticationType));
83+
this.UserClaims = this.ParseUserClaims(await this.EasyAuthService.GetUserClaims(this.IdentityProvider));
8184

8285
await Task.CompletedTask;
8386
}
8487

8588
protected async Task LoginAsync()
8689
{
87-
this.NavigationManager.NavigateTo("/.auth/login/done");
90+
var signedIn = await this.EasyAuthService.UserSignInAsync(this.HttpContext, this.IdentityProvider, this.UserId, this.Username, this.UserRoles, this.UserClaims);
91+
92+
if (signedIn)
93+
{
94+
this.NavigationManager.NavigateTo("/.auth/login/done");
95+
}
96+
97+
await Task.CompletedTask;
8898
}
8999

90100
protected async Task ClearAsync()
91101
{
92102
this.UserId = this.EasyAuthService.UserId.ToString("N");
93103
this.Username = string.Empty;
94104
this.UserRoles = this.ParseUserRoles(this.EasyAuthService.UserRoles);
95-
this.UserClaims = this.ParseUserClaims(await this.EasyAuthService.GetUserClaims(this.AuthenticationType));
105+
this.UserClaims = this.ParseUserClaims(await this.EasyAuthService.GetUserClaims(this.IdentityProvider));
96106

97107
await Task.CompletedTask;
98108
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Aliencube.Azure.Extensions.EasyAuth.Emulator.Models;
2+
3+
public enum IdentityProviderType
4+
{
5+
None,
6+
Apple,
7+
EntraID,
8+
Facebook,
9+
GitHub,
10+
Google,
11+
OpenIDConnect,
12+
Twitter,
13+
}

src/Aliencube.Azure.Extensions.EasyAuth.Emulator/Services/EasyAuthService.cs

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
1+
using System.Text;
12
using System.Text.Json;
23

4+
using Aliencube.Azure.Extensions.EasyAuth.Emulator.Models;
5+
36
namespace Aliencube.Azure.Extensions.EasyAuth.Emulator.Services;
47

58
public interface IEasyAuthService
69
{
710
JsonSerializerOptions JsonSerializerOptions { get; }
11+
812
Guid UserId { get; }
913

1014
IEnumerable<string> UserRoles { get; }
1115

12-
Task<IEnumerable<MsClientPrincipalClaim>> GetUserClaims(string? authenticationType);
16+
Task<IEnumerable<MsClientPrincipalClaim>> GetUserClaims(string? identityProvider);
17+
18+
Task<bool> UserSignInAsync(HttpContext? context, string? identityProvider, string? userId, string? username, string? userRoles, string? userClaims);
1319
}
1420

1521
public class EasyAuthService(UserIdGenerator userId) : IEasyAuthService
1622
{
1723
public JsonSerializerOptions JsonSerializerOptions { get; } = new() { WriteIndented = true };
24+
1825
public Guid UserId { get; } = userId.Value;
26+
1927
public IEnumerable<string> UserRoles { get; } = [ "User", "Admin" ];
20-
public async Task<IEnumerable<MsClientPrincipalClaim>> GetUserClaims(string? authenticationType)
28+
29+
public async Task<IEnumerable<MsClientPrincipalClaim>> GetUserClaims(string? identityProvider)
2130
{
2231
var claims = new List<MsClientPrincipalClaim>()
2332
{
@@ -28,4 +37,90 @@ public async Task<IEnumerable<MsClientPrincipalClaim>> GetUserClaims(string? aut
2837

2938
return await Task.FromResult(claims).ConfigureAwait(false);
3039
}
40+
41+
public async Task<bool> UserSignInAsync(HttpContext? context, string? identityProvider, string? userId, string? username, string? userRoles, string? userClaims)
42+
{
43+
var provider = ParseIdentityProvider(identityProvider);
44+
if (provider == IdentityProviderType.None)
45+
{
46+
return await Task.FromResult(false).ConfigureAwait(false);
47+
}
48+
49+
var clientPrincipal = provider switch
50+
{
51+
IdentityProviderType.EntraID => this.BuildEntraIDMsClientPrincipal(identityProvider, userId, username, userRoles, userClaims),
52+
IdentityProviderType.GitHub => this.BuildGitHubMsClientPrincipal(identityProvider, userId, username, userRoles, userClaims),
53+
_ => null,
54+
};
55+
56+
context!.Response.Headers.Append("X-MS-CLIENT-PRINCIPAL-NAME", username!);
57+
context!.Response.Headers.Append("X-MS-CLIENT-PRINCIPAL-ID", Guid.NewGuid().ToString());
58+
context!.Response.Headers.Append("X-MS-CLIENT-PRINCIPAL-IDP", identityProvider!);
59+
60+
var serialised = JsonSerializer.Serialize(clientPrincipal, JsonSerializerOptions);
61+
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(serialised));
62+
context!.Response.Headers.Append("X-MS-CLIENT-PRINCIPAL", encoded);
63+
64+
return await Task.FromResult(true).ConfigureAwait(false);
65+
}
66+
67+
private MsClientPrincipal BuildEntraIDMsClientPrincipal(string? identityProvider, string? userId, string? username, string? userRoles, string? userClaims)
68+
{
69+
var utcNow = DateTimeOffset.UtcNow;
70+
var defaultClaims = new List<MsClientPrincipalClaim>()
71+
{
72+
new() { Type = "aud", Value = userId },
73+
new() { Type = "iss", Value = "https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/v2.0" },
74+
new() { Type = "iat", Value = $"{utcNow.ToUnixTimeSeconds()}" },
75+
new() { Type = "nbf", Value = $"{utcNow.ToUnixTimeSeconds()}" },
76+
new() { Type = "nbf", Value = $"{utcNow.AddMinutes(90).ToUnixTimeSeconds()}" },
77+
new() { Type = "aio", Value = $"{Convert.ToBase64String(Guid.NewGuid().ToByteArray())}" },
78+
new() { Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", Value = username },
79+
new() { Type = "http://schemas.microsoft.com/identity/claims/identityprovider", Value = "https://sts.windows.net/00000000-0000-0000-0000-000000000000/" },
80+
};
81+
82+
var userRoleClaims = (userRoles?.Split('\n', StringSplitOptions.RemoveEmptyEntries) ?? []).Select(p => new MsClientPrincipalClaim() { Type = "roles", Value = p });
83+
var userClaimClaims = JsonSerializer.Deserialize<IEnumerable<MsClientPrincipalClaim>>(userClaims ?? "[]", JsonSerializerOptions) ?? [];
84+
85+
var claims = new List<MsClientPrincipalClaim>();
86+
claims.AddRange(defaultClaims);
87+
if (userRoleClaims.Any() == true)
88+
{
89+
claims.AddRange(userRoleClaims);
90+
}
91+
if (userClaimClaims.Any() == true)
92+
{
93+
var userClaimClaimsWithoutUsername = userClaimClaims.Where(p => p.Type!.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", StringComparison.InvariantCultureIgnoreCase) != true);
94+
claims.AddRange(userClaimClaimsWithoutUsername);
95+
}
96+
var principal = new MsClientPrincipal()
97+
{
98+
IdentityProvider = identityProvider,
99+
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
100+
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
101+
Claims = claims,
102+
};
103+
104+
return principal;
105+
}
106+
107+
private MsClientPrincipal BuildGitHubMsClientPrincipal(string? identityProvider, string? userId, string? username, string? userRoles, string? userClaims)
108+
{
109+
throw new NotImplementedException();
110+
}
111+
112+
private static IdentityProviderType ParseIdentityProvider(string? identityProvider)
113+
{
114+
if (string.IsNullOrWhiteSpace(identityProvider) == true)
115+
{
116+
return IdentityProviderType.None;
117+
}
118+
119+
if (identityProvider.Equals("aad", StringComparison.InvariantCultureIgnoreCase))
120+
{
121+
return IdentityProviderType.EntraID;
122+
}
123+
124+
return Enum.TryParse<IdentityProviderType>(identityProvider, true, out var result) ? result : IdentityProviderType.None;
125+
}
31126
}

0 commit comments

Comments
 (0)