[英]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.