我已经构建了一个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);
添加
HttpMessageHandlerAuthorizedUrls
apiurl
到应用设置(以开发为例):"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,这意味着托管)