[英]Server-side Blazor Autorize Attribute is not working
我有一個問題,授權屬性在頁面上不起作用,使用服務器端 Blazor。
我遵循了以下文檔: https://learn.microsoft.com/fr-fr/as.net/core/security/blazor/?view=as.netcore-3.1
還有https://gunnarpeipman.com/client-side-blazor-authorizeview/ ,有點過時了。
所以這是自定義提供程序:
using Microsoft.AspNetCore.Components.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace CustomAuth
{
public class MyAuthenticationStateProvider : AuthenticationStateProvider
{
public static bool IsAuthenticated { get; set; }
public static bool IsAuthenticating { get; set; }
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
ClaimsIdentity identity;
if (IsAuthenticating)
{
return null;
}
else if (IsAuthenticated)
{
identity = new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Name, "TestUser")
}, "WebApiAuth");
}
else
{
identity = new ClaimsIdentity();
}
return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(identity)));
}
public void NotifyAuthenticationStateChanged()
{
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
}
}
在我的 login.razor 中:
@page "/Login"
@using CustomAuth
@inject MyAuthenticationStateProvider MyAuthStateProvider
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
<button @onclick="@(() => UpdateAuthentication(true))">
Set authenticated
</button>
<button @onclick="@(() => UpdateAuthentication(false))">
Set anonymous
</button>
<button @onclick="@(() => UpdateAuthentication(null))">
Set authenticating
</button>
@code
{
private void UpdateAuthentication(bool? isAuthenticated)
{
if (!isAuthenticated.HasValue)
{
MyAuthenticationStateProvider.IsAuthenticating = true;
}
else
{
MyAuthenticationStateProvider.IsAuthenticating = false;
MyAuthenticationStateProvider.IsAuthenticated = isAuthenticated.Value;
}
MyAuthStateProvider.NotifyAuthenticationStateChanged();
}
在我的 index.razor 中:
@page "/"
@using System.Security.Claims
@using Microsoft.AspNetCore.Components.Authorization
@inject MyAuthenticationStateProvider MyAuthStateProvider
<h3>ClaimsPrincipal Data</h3>
<a href="/Login">Login</a>
<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>
<p>@_authMessage</p>
@if (_claims.Count() > 0)
{
<ul>
@foreach (var claim in _claims)
{
<li>@claim.Type – @claim.Value</li>
}
</ul>
}
<p>@_surnameMessage</p>
@code {
private string _authMessage;
private string _surnameMessage;
private IEnumerable<Claim> _claims = Enumerable.Empty<Claim>();
private async Task GetClaimsPrincipalData()
{
var authState = await MyAuthStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
_authMessage = $"{user.Identity.Name} is authenticated.";
_claims = user.Claims;
_surnameMessage =
$"Surname: {user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value}";
}
else
{
_authMessage = "The user is NOT authenticated.";
}
}
然后是我的 app.razor:
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<CascadingAuthenticationState>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</CascadingAuthenticationState>
</NotFound>
</Router>
我的 startup.cs:
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; }
public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddAuthenticationCore(); services.AddScoped<MyAuthenticationStateProvider>(); services.AddScoped<AuthenticationStateProvider>(provider => provider.GetRequiredService<MyAuthenticationStateProvider>()); services.AddRazorPages(); services.AddServerSideBlazor(); services.AddSingleton<WeatherForecastService>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/as.netcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); }); } }
問題是授權組件不工作,當我 go 到登錄頁面並授權后,我在點擊計數器組件時收到取消授權消息!
@page "/counter"
@attribute [Authorize]
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
任何幫助將不勝感激,我昨天一直試圖解決這個問題,直到凌晨 3 點都沒有成功!
非常感謝,
拉斐爾
我可以在您的代碼中找到阻止應用程序按預期運行的唯一原因與訂單有關。
此設置:
services.AddAuthenticationCore();
services.AddScoped<MyAuthenticationStateProvider>();
services.AddScoped<AuthenticationStateProvider>(provider =>
provider.GetRequiredService<MyAuthenticationStateProvider>());
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
應該這樣訂購:
services.AddAuthenticationCore();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddScoped<MyAuthenticationStateProvider>();
services.AddScoped<AuthenticationStateProvider>(provider =>
provider.GetRequiredService<MyAuthenticationStateProvider>());
services.AddSingleton<WeatherForecastService>();
您首先必須添加 Razor Pages 服務和 Blazor Server App 服務,然后才添加自定義服務。
運行您的應用程序,單擊 Counter... Not Authorized 文本顯示。 Go 回到Index頁面,點擊login,然后選擇Set Authenticated。 現在 go 返回計數器頁面... 允許訪問。
現在嘗試自動執行此操作...當我單擊計數器時,它應該將我重定向到登錄頁面,當我單擊設置身份驗證時,它會將我重定向到計數器頁面(允許訪問)。
希望這可以幫助...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.