首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >服务器端Blazor Autorize属性不工作。

服务器端Blazor Autorize属性不工作。
EN

Stack Overflow用户
提问于 2020-05-17 17:19:51
回答 1查看 2.3K关注 0票数 2

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

我遵循了以下文档:https://learn.microsoft.com/fr-fr/aspnet/core/security/blazor/?view=aspnetcore-3.1

还有https://gunnarpeipman.com/client-side-blazor-authorizeview/,它有点过时了。

以下是自定义提供者:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
@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中:

代码语言:javascript
运行
复制
@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:

代码语言:javascript
运行
复制
<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:

代码语言:javascript
运行
复制
`public class Startup     {         public Startup(IConfiguration configuration)         {             Configuration = configuration;         }`
代码语言:javascript
运行
复制
    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");
        });
    }
}

问题是授权组件不起作用,当我转到登录页面时,当我授权后,当我点击计数器组件时,我就会得到不授权消息!

代码语言:javascript
运行
复制
@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点才成功!

非常感谢,

拉斐尔

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-18 20:01:19

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

这一背景:

代码语言:javascript
运行
复制
    services.AddAuthenticationCore();
    services.AddScoped<MyAuthenticationStateProvider>();
    services.AddScoped<AuthenticationStateProvider>(provider => 
    provider.GetRequiredService<MyAuthenticationStateProvider>());
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();  

应该像这样下命令:

代码语言:javascript
运行
复制
    services.AddAuthenticationCore();
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddScoped<MyAuthenticationStateProvider>();
    services.AddScoped<AuthenticationStateProvider>(provider => 
    provider.GetRequiredService<MyAuthenticationStateProvider>());
    services.AddSingleton<WeatherForecastService>();

首先必须添加Razor Pages服务和Blazor Server App服务,然后才添加自定义服务。

运行你的应用程序点击计数器..。显示未授权的文本。返回到“索引”页面,单击“登录”,然后选择“设置身份验证”。现在回到柜台..。允许进入。

现在试着自动完成..。当我单击“计数器”时,它应该将我重定向到登录页,而当我单击“设置身份验证”时,它将我重定向到计数器页(允许访问)。

希望这能帮上忙。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61855833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档