Αυτή η ανάρτηση δείχνει πώς να εφαρμόσετε ένα Blazor WASM UI που φιλοξενείται σε μια εφαρμογή ASP.NET Core χρησιμοποιώντας πολλαπλούς παρόχους ταυτότητας για έλεγχο ταυτότητας. Δύο εμπιστευτικοί πελάτες ροής κώδικα OpenID Connect με PKCE χρησιμοποιούνται για την εφαρμογή του ελέγχου ταυτότητας Blazor. Το Blazor WASM και η εφαρμογή ASP.NET Core αποτελούν ένα ενιαίο πλαίσιο ασφαλείας. Αυτό υλοποιείται χρησιμοποιώντας το backend για την αρχιτεκτονική ασφαλείας του frontend.
Κώδικας: https://github.com/damienbod/ApiJwtWithTwoSts
Ρύθμιση
Δύο πάροχοι ταυτότητας υλοποιούνται χρησιμοποιώντας OpenIddict με ASP.NET Core Identity. Οποιοσδήποτε πάροχος ταυτότητας OpenID Connect μπορεί να χρησιμοποιηθεί εδώ. Ο πάροχος ταυτότητας εφαρμόζει έναν εμπιστευτικό πελάτη που απαιτεί ένα μυστικό. Η ροή κώδικα OpenID Connect χρησιμοποιείται για την υλοποίηση της ροής ελέγχου ταυτότητας.

Η εφαρμογή Blazor ρυθμίστηκε χρησιμοποιώντας το Blazor.BFF.OpenIDConnect.Template που μπορεί να εγκατασταθεί και να χρησιμοποιηθεί από το Visual Studio ή το εργαλείο dotnet cmd. Το πρότυπο δημιουργεί μια εφαρμογή ASP.NET Core με προβολή WASM και προεπιλεγμένους ορισμούς για τη ροή κώδικα OIDC.
Blazor έλεγχος ταυτότητας
Η εφαρμογή Blazor απαιτεί δύο υλοποιήσεις πελάτη OIDC. Ο χρήστης της εφαρμογής μπορεί να επιλέξει το απαιτούμενο IDP. ο DefaultChallengeScheme έχει οριστεί σε „ΑΓΝΩΣΤΟ“ και αυτό δεν έχει ορισμό. Η σύνδεση ή η σύνδεση πρέπει να ορίσει το σχήμα ελέγχου ταυτότητας για την πρόκληση. Η διεύθυνση URL ανακατεύθυνσης και η διεύθυνση URL αποσύνδεσης πρέπει να οριστούν ρητά και δεν μπορούν να αντιστοιχούν σε ορισμό από διαφορετική πρόκληση.
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "UNKNOWN";
})
.AddCookie()
.AddOpenIdConnect("T1", options =>
{
configuration.GetSection("OpenIDConnectSettingsT1").Bind(options);
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.CallbackPath = "/signin-oidc-t1";
options.SignedOutCallbackPath = "/signout-callback-oidc-t1";
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.Scope.Add("profile");
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
})
.AddOpenIdConnect("T2", options =>
{
configuration.GetSection("OpenIDConnectSettingsT2").Bind(options);
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.ResponseType = OpenIdConnectResponseType.Code;
options.CallbackPath = "/signin-oidc-t2";
options.SignedOutCallbackPath = "/signout-callback-oidc-t2";
options.SaveTokens = true;
options.Scope.Add("profile");
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
ο Ελεγκτής λογαριασμού υλοποιεί τα αιτήματα σύνδεσης και αποσύνδεσης. Η σύνδεση πρέπει να επιβάλει τη σύνδεση για το σωστό σχήμα. Ονόμασα τα σχέδιά μου Τ1 και Τ2.
[HttpGet("LoginT1")]
public IActionResult T1(string returnUrl)
{
var redirectUrl = !string.IsNullOrEmpty(returnUrl) ? returnUrl : "/";
return Challenge(new AuthenticationProperties
{ RedirectUri = redirectUrl }, "T1");
}
[HttpGet("LoginT2")]
public IActionResult T2(string returnUrl)
{
var redirectUrl = !string.IsNullOrEmpty(returnUrl) ? returnUrl : "/";
return Challenge(new AuthenticationProperties
{ RedirectUri = redirectUrl }, "T2");
}
ο CallbackPath πρέπει να είναι μοναδικό στην εφαρμογή και απαιτείται ξεχωριστός ορισμός για κάθε πάροχο ταυτότητας.
Αποσύνδεση πελάτη Blazor
Η αποσύνδεση λειτουργεί λίγο σαν τη σύνδεση. Πρέπει να έχετε έναν μοναδικό ορισμό SignedOutCallbackPath για κάθε σχήμα. Πρόσθεσα μια νέα αξίωση στο διακριτικό id_token από τον πάροχο ταυτότητας. Πρόσθεσα αυτήν την αξίωση στον διακομιστή OpenIddict. Μόλις γίνει έλεγχος ταυτότητας του χρήστη, η αξίωση idp μπορεί να χρησιμοποιηθεί για να επαληθεύσει ποιος πάροχος ταυτότητας χρησιμοποιήθηκε για έλεγχο ταυτότητας. Η αξίωση απαιτείται για την αποσύνδεση που στέλνει ένα αίτημα στον σωστό πάροχο ταυτότητας.
[ValidateAntiForgeryToken]
[Authorize]
[HttpPost("Logout")]
public IActionResult Logout()
{
var authProperties = new AuthenticationProperties
{
RedirectUri = "/"
};
// custom claims added to idp, you need to
// implement something on your idp for this
var usedT1ForAuthn = User.Claims.Any(
idpClaim => idpClaim.Type == "idp" && idpClaim.Value == "T1");
var usedT2ForAuthn = User.Claims.Any(
idpClaim => idpClaim.Type == "idp" && idpClaim.Value == "T2");
if(usedT1ForAuthn)
return SignOut(authProperties,
CookieAuthenticationDefaults.AuthenticationScheme, "T1");
if (usedT2ForAuthn)
return SignOut(authProperties,
CookieAuthenticationDefaults.AuthenticationScheme, "T2");
return SignOut(authProperties,
CookieAuthenticationDefaults.AuthenticationScheme);
}
Το προσαρμοσμένο „idp“ χρησιμοποιείται επίσης για την εμφάνιση του παρόχου ταυτότητας στο Blazor WASM UI.
<Authorized>
<strong>@context?.User?.Identity?.Name idp:
@context?.User?.Claims.FirstOrDefault(c => c.Type == "idp")?.Value
</strong>
<form method="post" action="api/Account/Logout">
<AntiForgeryTokenInput />
<button class="btn btn-link" type="submit">Signout</button>
</form>
</Authorized>
Ο χρήστης μπορεί να συνδεθεί χρησιμοποιώντας διαφορετικούς παρόχους ταυτότητας.

Η αξίωση ονόματος και ο πάροχος ταυτότητας εμφανίζονται στη διεπαφή χρήστη.

Σημειώσεις
Η χρήση πολλαπλών παρόχων ταυτότητας στο ASP.NET Core είναι μια απλή υλοποίηση αφού κατανοήσετε την έννοια του σχήματος και τα συμβάντα ροής ελέγχου ταυτότητας που χρησιμοποιούνται. Εάν χρησιμοποιείτε πελάτες ελέγχου ταυτότητας περιτυλίγματος μιας γραμμής από διαφορετικούς παρόχους, πρέπει να παρακάμψετε την προεπιλεγμένη υλοποίηση που είναι κρυμμένη μέσα σε αυτές τις βιβλιοθήκες. Τα περισσότερα από αυτά τα πακέτα παρέχουν μεθόδους επέκτασης και συμβάσεις για αυτό, αλλά μερικές φορές είναι πιο απλό να χρησιμοποιήσετε την τυπική υλοποίηση ASP.NET Core. Αυτό λειτουργεί για οποιονδήποτε διακομιστή OpenID Connect συμμορφώνεται.
Συνδέσεις
https://documentation.openiddict.com/configuration/claim-destinations.html
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/claims
https://www.nuget.org/packages/Blazor.BFF.OpenIDConnect.Template