Wsparcie
Zadaj pytania na Stack Overflow i oznacz tagiem 'itfoxtec-identity-blazor'.
E-mail support@foxids.com z linkiem do pytania.
Pakiet
Wydania
NuGet ITfoxtec Identity Blazor WebAssembly OpenID Connect
Kod i licencja
Kod i sample na GitHub
Licencja open-source
ITfoxtec Identity Blazor WebAssembly OpenID Connect
ITfoxtec Identity Blazor WebAssembly OpenID Connect to bez-JavaScriptowa biblioteka OpenID Connect PKCE dla Blazor WebAssembly.
Nazwa firmy ITfoxtec została zmieniona na FoxIDs ale komponenty na razie zachowają nazwę ITfoxtec jako część nazwy komponentu.
Obsługiwane wersje .NET:
- .NET 10.0
- .NET 9.0
- .NET 8.0
- .NET 7.0
- .NET 6.0
- .NET 5.0
Biblioteka obsługuje logowanie i wylogowanie z OpenID Connect z użyciem PKCE zamiast client secret. Waliduje tokeny ID w przeglądarce, korzystając z dokumentu discovery dostawcy OpenID.
Komponent automatycznie obsługuje odświeżanie tokenów i sesji przy użyciu refresh tokenów, gdy zakres offline_access jest określony.
Proszę zobaczyć przykładową aplikację.
Możesz użyć narzędzia JWT do dekodowania tokenów i tworzenia certyfikatów samopodpisanych za pomocą narzędzia certyfikatów.
Przykładowa aplikacja
Proszę zobaczyć przykładową aplikację w celu uzyskania szczegółów implementacji.
Przykładowa aplikacja jest skonfigurowana do uwierzytelniania z foxids.com używając testowego użytkownika test1@foxids.com lub test2@foxids.com i hasła TestAccess!
Aby dowiedzieć się więcej o European Identity Services FoxIDs, zobacz dokumentację FoxIDs.
Instalacja
Zainstaluj pakiet NuGet ITfoxtec.Identity.BlazorWebAssembly.OpenidConnect przez menedżer pakietów Visual Studio.
Lub zainstaluj przez PowerShell, używając poniższego polecenia.
Install-Package ITfoxtec.Identity.BlazorWebAssembly.OpenidConnect
Lub przez CLI.
dotnet add package ITfoxtec.Identity.BlazorWebAssembly.OpenidConnect
Konfiguracja i ustawienia
Zarejestruj OpenidConnectPkce, HttpClient oraz IHttpClientFactory w pliku Program.cs.
private static void ConfigureServices(IServiceCollection services, WebAssemblyHostConfiguration configuration, IWebAssemblyHostEnvironment hostEnvironment)
{
services.AddHttpClient("BlazorWebAssemblyOidcSample.API", client => client.BaseAddress = new Uri(hostEnvironment.BaseAddress))
.AddHttpMessageHandler<AccessTokenMessageHandler>();
services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("BlazorWebAssemblyOidcSample.API"));
services.AddOpenidConnectPkce(settings =>
{
configuration.Bind("IdentitySettings", settings);
});
}
Dodaj pliki konfiguracji appsettings.json i ewentualnie appsettings.Development.json w wwwroot z konfiguracją IdentitySettings. Zakres jest podawany jako lista wartości oddzielonych spacją.
{
"IdentitySettings": {
"Authority": "https://...some authority.../",
"ClientId": "...client id...",
"Scope": "...some scope..."
}
}
Dodaj przestrzeń nazw biblioteki @using ITfoxtec.Identity.BlazorWebAssembly.OpenidConnect do Imports.razor.
Konfiguracja IdP
Skonfiguruj klienta Blazor jako klienta OpenID Connect po stronie IdP.
- Typy odpowiedzi: code
- Włącz PKCE: true
- Login callback: ...bazowy URL.../authentication/login_callback
- Logout callback: ...bazowy URL.../authentication/logout_callback
Wywołania API do innej domeny
Konfigurację można rozszerzyć, aby obsługiwać wywołania API do domen innych niż domena bazowa. Zaufane AuthorizedUris w konfiguracji IdentitySettings są ustawiane na AccessTokenMessageHandler.
private static void ConfigureServices(IServiceCollection services, WebAssemblyHostConfiguration configuration, IWebAssemblyHostEnvironment hostEnvironment)
{
services.AddHttpClient("BlazorWebAssemblyOidcSample.API", client => client.BaseAddress = new Uri(hostEnvironment.BaseAddress))
.AddHttpMessageHandler(sp =>
{
var handler = sp.GetService<AccessTokenMessageHandler>();
configuration.Bind("IdentitySettings", handler);
return handler;
});
services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("BlazorWebAssemblyOidcSample.API"));
services.AddOpenidConnectPkce(settings =>
{
configuration.Bind("IdentitySettings", settings);
});
}
Dodaj zaufane domeny jako AuthorizedUris w konfiguracji IdentitySettings.
{
"IdentitySettings": {
"Authority": "https://...some authority.../",
"ClientId": "...client id...",
"Scope": "...some scope...",
"Resources": [ "...resource..." ],
"AuthorizedUris": [ "...authorized api Uri..." ]
}
}
Okresowa walidacja tokenu dostępu
Ustaw SessionValidationIntervalSeconds w IdentitySettings (domyślnie 300; ustaw 0, aby wyłączyć).
Gdy włączone, OidcAuthenticationStateProvider okresowo wywołuje endpoint UserInfo przez OidcHelper.ValidateAccessTokenWithUserInfoEndpoint.
Jeśli walidacja się nie powiedzie, dostawca czyści sesję i wywołuje zdarzenie wylogowania, aby UI mogło poprosić użytkownika o ponowne logowanie.
Dodaj stronę callback
Dodaj stronę Authentication.razor w folderze Pages z następującą zawartością.
@page "/authentication/{action}"
@inherits AuthenticationPageBase
Autoryzuj widoki
Zaktualizuj App.razor, aby uwzględnić AuthorizeRouteView/NotAuthorized z elementem OidcRedirectToLogin. OidcRedirectToLogin uruchamia logowanie, jeśli użytkownik nie ma dostępu.
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
<OidcRedirectToLogin />
</NotAuthorized>
<Authorizing>
<h1>Authentication in progress</h1>
<p>Only visible while authentication is in progress.</p>
</Authorizing>
</AuthorizeRouteView>
</Found>
<NotFound>
<CascadingAuthenticationState>
<LayoutView Layout="@typeof(MainLayout)">
<h1>Sorry</h1>
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</CascadingAuthenticationState>
</NotFound>
</Router>
W efekcie obsługiwane są zarówno atrybut Authorize, jak i AuthorizeView.
Menu logowania/wylogowania
Dodaj LoginDisplay.razor z menu logowania/wylogowania o następującej treści.
@inject OpenidConnectPkce oenidConnectPkce
<AuthorizeView>
<Authorized>
Hello, @context.User.Identity.Name!
<button class="nav-link btn btn-link" @onclick="LogoutAsync">Logout</button>
</Authorized>
<NotAuthorized>
<button class="nav-link btn btn-link" @onclick="LoginAsync">Login</button>
</NotAuthorized>
</AuthorizeView>
@code{
private async Task LoginAsync(MouseEventArgs args)
{
await oenidConnectPkce.LoginAsync();
}
private async Task LogoutAsync(MouseEventArgs args)
{
await oenidConnectPkce.LogoutAsync();
}
}
LoginDisplay można dodać do MainLayout.razor w ten sposób.
@inherits LayoutComponentBase
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
<LoginDisplay />
</div>
<div class="content px-4">
@Body
</div>
</div>