Przykładowa aplikacja
Proszę zobaczyć przykładową aplikację w celu uzyskania szczegółów implementacji.
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.
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>