简体   繁体   English

服务器端 Blazor Autorize 属性不起作用

[英]Server-side Blazor Autorize Attribute is not working

I have a problem, the authorize attribute is not working on a page, using Server-side Blazor.我有一个问题,授权属性在页面上不起作用,使用服务器端 Blazor。

I have followed the following docs: https://learn.microsoft.com/fr-fr/as.net/core/security/blazor/?view=as.netcore-3.1我遵循了以下文档: https://learn.microsoft.com/fr-fr/as.net/core/security/blazor/?view=as.netcore-3.1

And https://gunnarpeipman.com/client-side-blazor-authorizeview/ , which is a bit outdated.还有https://gunnarpeipman.com/client-side-blazor-authorizeview/ ,有点过时了。

So here's the custom provider:所以这是自定义提供程序:

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());
        }
    }
}

In my login.razor:在我的 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();
    }

And in my index.razor:在我的 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 &ndash; @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.";
        }
    }

And then my app.razor:然后是我的 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>

My startup.cs:我的 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"); }); } }

The problem is the authorize component is not working, when I go to the login page and after I authorize, I get the Unauthorize message when I click on the counter component !问题是授权组件不工作,当我 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++;
    }
}

Any help would really be appreciated, I have tried to solve this problem yesterday until 3 am without success!任何帮助将不胜感激,我昨天一直试图解决这个问题,直到凌晨 3 点都没有成功!

Many thanks,非常感谢,

Raphaël拉斐尔

The only reason I could locate in your code that prevent the app from working as intended is related to order.我可以在您的代码中找到阻止应用程序按预期运行的唯一原因与订单有关。

This setting:此设置:

    services.AddAuthenticationCore();
    services.AddScoped<MyAuthenticationStateProvider>();
    services.AddScoped<AuthenticationStateProvider>(provider => 
    provider.GetRequiredService<MyAuthenticationStateProvider>());
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();  

Should be ordered like this:应该这样订购:

    services.AddAuthenticationCore();
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddScoped<MyAuthenticationStateProvider>();
    services.AddScoped<AuthenticationStateProvider>(provider => 
    provider.GetRequiredService<MyAuthenticationStateProvider>());
    services.AddSingleton<WeatherForecastService>();

You first have to add the Razor Pages services and the Blazor Server App services, and only then add custom services.您首先必须添加 Razor Pages 服务和 Blazor Server App 服务,然后才添加自定义服务。

Run your app, click Counter... Not Authorized text is displayed.运行您的应用程序,单击 Counter... Not Authorized 文本显示。 Go back to the Index page, click login, and then choose Set Authenticated. Go 回到Index页面,点击login,然后选择Set Authenticated。 Now go back to the Counter page... Access is allowed.现在 go 返回计数器页面... 允许访问。

Now try to do that automatically... When I click Counter, it should redirect me to the login page, and when I click set authenticated, it redirects me to the Counter page (access allowed).现在尝试自动执行此操作...当我单击计数器时,它应该将我重定向到登录页面,当我单击设置身份验证时,它会将我重定向到计数器页面(允许访问)。

Hope this helps...希望这可以帮助...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM