簡體   English   中英

Blazor WebAssembly 401 未經授權,即使我被授權

[英]Blazor WebAssembly 401 Unauthorized even when I am authorized

我正在使用Blazor WebAssembly Asp.Net Core hosted PWA並將AspNetCore.Identity集成到其中。 我在客戶端創建了AuthenticationStateProvider ,現在我想允許用戶訪問需要授權的 controller。

我已經通過 postman 進行了測試,用戶已創建並作為具有正確憑據的aspnetusers存儲在數據庫中。 登錄/帳戶 Controller 按我的意願工作。

當用戶獲得授權時,它會在訪問授權的 controller 請求時在瀏覽器中顯示此異常:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未處理的異常渲染組件:響應狀態碼不表示成功:401(未授權)。 System.Net.Http.HttpRequestException:響應狀態碼不表示成功:401(未授權)。

Startup.cs( ConfigureServices -方法):

...
    serviceCollection.AddDbContext<SQLiteTestDbContext>(options =>
                {
                    options.UseSqlite(config["ConnectionStrings:SQLiteTestConnection"]);
                });
                serviceCollection.AddDefaultIdentity<IdentityUser>()
                    .AddEntityFrameworkStores<SQLiteTestDbContext>()
                    .AddDefaultTokenProviders();

    services.AddAuthentication(x =>
                    {
                        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    })
                    .AddJwtBearer(options =>
                    {
                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuer = true,
                            ValidateAudience = true,
                            ValidateLifetime = true,
                            ValidateIssuerSigningKey = true,
                            ValidIssuer = Configuration["JwtIssuer"],
                            ValidAudience = Configuration["JwtAudience"],
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecurityKey"]))
                        };
                    });

    services.AddHttpContextAccessor();
                services.Configure<IdentityOptions>(options =>
                    options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);
...

 

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      
    ...
        app.UseAuthentication();
        app.UseAuthorization();
    ...
    }

Program.cs 客戶端


    public static async Task Main(string[] args)
            {
                var builder = WebAssemblyHostBuilder.CreateDefault(args);
                builder.RootComponents.Add<App>("app");
                builder.Logging.SetMinimumLevel(LogLevel.Warning);
    
                //Registering Shared-Library models
                builder.Services.AddScoped<ObjectModel>();

                builder.Services.AddBlazoredLocalStorage();
                builder.Services.AddAuthorizationCore();
                builder.Services.AddScoped<AuthenticationStateProvider, ApiAuthenticationStateProvider>();
                builder.Services.AddScoped<IAuthService, AuthService>();
    
                //Registered BlazorContextMenu Service
                builder.Services.AddBlazorContextMenu();
    
                //Registering FileReader service, for image upload -> Azure
                builder.Services.AddFileReaderService(options => options.UseWasmSharedBuffer = true);
                builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
    
                await builder.Build().RunAsync();
            }

我的 Controller 具有授權屬性:


    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
        [Route("api/[controller]")]
        [ApiController]
        public class ObjectController : ControllerBase
        {
....
    

筆記:

  1. 當您的用戶嘗試訪問客戶端上受保護的(使用 Authorize 屬性注釋的)頁面時,他應該首先登錄或注冊。

  2. 為了注冊,他應該被重定向到一個帳戶 Controller,您應該在其中創建一個新用戶,並將其添加到數據庫中(您說您“將 AspNetCore.Identity 集成到其中”),這很好......應該用於驗證和驗證用戶的身份。 您的帳戶 controller 還應該生成一個 Jwt 令牌,該令牌應該傳遞給客戶端應用程序,並存儲在本地存儲中。

  3. Now, whenever your user tries to access protected resources on your Web Api endpoints, you should retrieve the Jwt Token from the local storage, and add it to the request header. 如果您這樣做,未經授權的響應將成為過去。

  4. 自定義 AuthenticationStateProvider 可以是一個好地方,您可以從中管理將 Jwt 令牌存儲在本地存儲中,並為出站 HTTP 請求調用檢索它。

這里有一些示例代碼來闡明你應該做什么:

@code {
    WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        var token = await TokenProvider.GetTokenAsync();
        forecasts = await Http.GetJsonAsync<WeatherForecast[]>(
            "api/WeatherForecast",
            new AuthenticationHeaderValue("Bearer", token));
    }
}

注意:TokenProvider 是一個自定義的 AuthenticationStateProvider,它定義了一個名為 GetTokenAsync 的方法,該方法提供(從本地存儲讀取 Jwt 令牌並將其傳遞給調用代碼)Jwt 令牌

希望這可以幫助...

如果 Linux App Service 與 ID 服務器結合使用,則需要根據 Microsoft 文檔設置授權: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?視圖=aspnetcore-5.0#azure-app-service-on-linux-1

services.Configure<JwtBearerOptions>(
    IdentityServerJwtConstants.IdentityServerJwtBearerScheme, 
    options =>
    {
        options.Authority = "{AUTHORITY}";
    });

示例: options.Authority = "https://contoso-service.azurewebsites.net";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM