Blazor WASM:添加带有自定义API的JWT授权



我已经构建了一个API来控制一些智能家居的东西。为了防止整个互联网这样做,我添加了使用JWT/Bearer的身份验证。API包含智能家居的端点以及一些用户管理:用户的API端点

如果凭据有效,登录将返回一个JWT令牌。它也是使用。net 6构建的:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
};
});

登录控制器:

[HttpPost]
public async Task<IActionResult> Login([FromBody] UserLogin login)
{
var user = await _userService.GetUser(login.Username);
if (user is not null && _userService.IsPasswordCorrect(user, login.Password))
{
var tokens = await _userService.GetJwtAndRefreshToken(user);
return Ok(new LoginResponse { JWT = tokens.Jwt, RefreshToken = tokens.Refreshtoken });
}
return Unauthorized("Wrong username or password!");
}

现在我正在尝试使用blazor为这个应用程序构建一个前端。在创建应用程序时,我使用了"个人用户帐户"选项。进行身份验证。文档在这里:https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-authentication-library?view=aspnetcore-6.0&tabs=visual-studio

这在blazow WASM应用程序中创建了以下内容:

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddOidcAuthentication(options =>
{
// Configure your authentication provider options here.
// For more information, see https://aka.ms/blazor-standalone-auth
builder.Configuration.Bind("Local", options.ProviderOptions);
});
await builder.Build().RunAsync();

appsettings。Json是这样的:

{
"Local": {
"Authority": "https://localhost:7110/login",
"ClientId": "33333333-3333-3333-33333333333333333"
}
}

我将权限更改为我的登录api url,但似乎还不够。点击默认添加的登录按钮会触发这个请求:请求

是否有一个简单的方法来使用MS授权框架与我的自定义api?

我在这上面花了很多时间。这些是我的笔记。注意,我使用的是IdentityServer。可能很多事情对你来说都不一样。但它至少应该指导你检查什么。

它(对我来说)有效,但最佳实践不能保证。

我的API地址在端口5001,客户端在端口5101

For Client project

  • 在Client中修改HttpClient地址。更改Http MessageHandler。更改公共客户端地址
var clientBaseAddress = new Uri(builder.Configuration["apiurl"] ?? throw new ArgumentNullException("apirul is null (reading from config file)"));
builder.Services.AddHttpClient("BlazorApp6.ServerAPI", client =>client.BaseAddress = clientBaseAddress)
.AddHttpMessageHandler(sp =>
{//this is need when api is separated. https://code-maze.com/using-access-token-with-blazor-webassembly-httpclient/
var handler = sp.GetService<AuthorizationMessageHandler>()!
.ConfigureHandler(
authorizedUrls: new[] { builder.Configuration["HttpMessageHandlerAuthorizedUrls"] },
scopes: new[] { "BlazorApp6.ServerAPI" }
);
return handler;
});
builder.Services.AddHttpClient<PublicClient>(client => client.BaseAddress = clientBaseAddress);
  • 添加HttpMessageHandlerAuthorizedUrlsapiurl到应用设置(以开发为例):

    "apiurl": "https://localhost:5001",
    "HttpMessageHandlerAuthorizedUrls": "https://localhost:5001",
    
  • Program.cs AddApiAuthorization is different (set opt.ProviderOptions.ConfigurationEndpoint)

    builder.Services.AddApiAuthorization(
    //this line is only when address of api consumer is different 
    opt => opt.ProviderOptions.ConfigurationEndpoint = builder.Configuration["ApiAuthorizationConfigurationEndpoint"]
    ).AddAccountClaimsPrincipalFactory<CustomUserFactory>();
    
  • 添加ApiAuthorizationConfigurationEndpoint到appsettings

    "ApiAuthorizationConfigurationEndpoint": "https://localhost:5001/_configuration/BlazorApp6.Client"
    
  • 将launchSetting更改为不同端口

    "applicationUrl": "https://localhost:5101;http://localhost:5100",
    

对于api项目

  • 添加cors到客户端应用

    string developmentCorsPolicy = "dev_cors";
    services.AddCors(opt =>
    {
    opt.AddPolicy(name: developmentCorsPolicy, builder =>
    {
    builder.WithOrigins("https://localhost:5101", "https://localhost:5201")
    .WithMethods("GET", "POST", "PUT", "DELETE")
    .AllowAnyHeader();
    });
    });
    //...
    if (app.Environment.IsDevelopment())
    app.UseCors(developmentCorsPolicy);
    
  • 可能需要为身份服务器添加cors,但是没有它也可以工作。

    • 如果需要的话:

      services.AddSingleton<ICorsPolicyService>((container) =>
      {
      var logger = container.GetRequiredService<ILogger<DefaultCorsPolicyService>>();
      return new DefaultCorsPolicyService(logger)
      {
      AllowAll = true
      };
      });
      
  • 更改appsettings IdentityServer部分,以获得有关客户端的一些信息。

    • 此信息在OidcController中获得,请求以_configuration开头:

      "IdentityServer": {
      "Clients": {
      "BlazorApp6.Client": {
      "Profile": "SPA",
      "LogoutUri": "https://localhost:5101/authentication/logout-callback",
      "RedirectUri": "https://localhost:5101/authentication/login-callback"
      },
      },
      "Key": {
      "Type": "Development"
      } }
      
    • 请注意,Profile已更改为SPA(而不是IdentityServerSPA,这意味着托管)

相关内容

  • 没有找到相关文章

最新更新