【问题标题】:Server-side Blazor Autorize Attribute is not working服务器端 Blazor Autorize 属性不起作用
【发布时间】:2020-09-03 10:32:36
【问题描述】:

我有一个问题,授权属性在页面上不起作用,使用服务器端 Blazor。

我遵循了以下文档:https://docs.microsoft.com/fr-fr/aspnet/core/security/blazor/?view=aspnetcore-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 &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.";
        }
    }

然后是我的 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/aspnetcore-hsts.
            app.UseHsts();
        }                        


        app.UseHttpsRedirection();
        app.UseStaticFiles();            

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapBlazorHub();
            endpoints.MapFallbackToPage("/_Host");
        });
    }
}

问题是授权组件不起作用,当我进入登录页面并授权后,单击计数器组件时收到 Unauthorize 消息!

@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 点没有成功!

非常感谢,

拉斐尔

【问题讨论】:

    标签: c# .net authentication blazor


    【解决方案1】:

    我可以在您的代码中找到阻止应用按预期工作的唯一原因与订单有关。

    此设置:

        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 服务,然后才添加自定义服务。

    运行您的应用程序,单击计数器...显示未授权文本。返回索引页面,单击登录,然后选择设置已验证。现在返回计数器页面...允许访问。

    现在尝试自动执行此操作...当我单击计数器时,它应该将我重定向到登录页面,当我单击设置身份验证时,它将我重定向到计数器页面(允许访问)。

    希望这会有所帮助...

    【讨论】:

      猜你喜欢
      • 2020-01-05
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 2022-06-26
      • 2022-11-09
      • 1970-01-01
      • 2020-02-11
      相关资源
      最近更新 更多