在 Blazor wasm 中自动将身份 Cookie 附加到 HTTP 客户端
Automatically Attaching Identity Cookie to HTTP Client in Blazor wasm
我正在开发一个 blazor 应用程序,我在其中使用我的 API 项目作为标识
提供商。一切正常,但问题是访问令牌
由我的 API 发布,未被 API 验证。事实证明 API 期待
cookie header。我仔细查看了 blazor 托管应用程序并发现
cookie 随每个请求一起发送,但它是 same-origin。
我的 Blazor WASM 项目不会自动在请求中附加此 cookie
header,只是访问令牌。
有没有办法让 Http 处理程序在每个请求上附加此 cookie?
或者让 API 验证访问令牌而不是身份 cookie。
这是我在 API 项目
中的启动 class
public static void AddIdentityServer(IServiceCollection services,IConfiguration configuration)
{
services.AddIdentityServer(options =>
{
options.UserInteraction.LoginUrl = "/Identity/Account/Login";
options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
}).AddProfileService<LocalProfileService>()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(option =>
{
option.Clients.Add(new Client
{
ClientId = "blazor",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
AllowedCorsOrigins = { "https://localhost:5001" },
AllowedScopes = { "openid", "profile", "email","id" },
RedirectUris = { "https://localhost:5001/authentication/login-callback" },
PostLogoutRedirectUris = { "https://localhost:5001/" },
Enabled = true,
RequireConsent = false,
});
option.IdentityResources.AddEmail();
option.IdentityResources["openid"].UserClaims.Add("name");
option.ApiResources.Single().UserClaims.Add("name");
option.IdentityResources["openid"].UserClaims.Add("role");
option.ApiResources.Single().UserClaims.Add("role");
option.IdentityResources.Add(new IdentityResource("id",new string[] {"id" }));
option.ApiResources.Single().UserClaims.Add("id");
});
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.ClientId = configuration["ExternalLoginApiKey:GoogleClientId"];
options.ClientSecret = configuration["ExternalLoginApiKey:GoogleClientSecret"];
})
.AddFacebook("Facebook", options =>
{
options.AppId = configuration["ExternalLoginApiKey:FacebookAppId"];
options.AppSecret = configuration["ExternalLoginApiKey:FacebookAppSecret"];
})
.AddIdentityServerJwt();
}
Blazor 项目中的程序 class
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = "role";
}).AddAccountClaimsPrincipalFactory<CustomUserFactory>();
builder.Services.AddHttpClient<IAuthorizedRestService, AuthorizedRestService>(
client => client.BaseAddress = new Uri("https://localhost:5002/api/mart/v1/"))
.AddHttpMessageHandler(sp => sp.GetRequiredService<AuthorizationMessageHandler>()
.ConfigureHandler(authorizedUrls: new[] { "https://localhost:5002" }));
builder.Services.AddHttpClient("noauth", option => option.BaseAddress = new
Uri("https://localhost:5002/api/mart/v1/"));
builder.Services.AddScoped<IRestService, RestService>();
await builder.Build().RunAsync();
}
我找到了解决方案。
碰巧 IdentityServer4 已经为兼作授权服务器的 API 提供了一个 JWT 处理程序
.AddIdentityServerJwt();
所以我所做的就是配置它
services.Configure<JwtBearerOptions>
(IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.Authority = "https://localhost:5002";
options.Audience = "mart";
options.SaveToken = true;
});
然后指定要使用的身份验证方案
[Authorize(AuthenticationSchemes = IdentityServerJwtConstants.IdentityServerJwtBearerScheme)]
也可以在启动时全局添加class
var authorizationPolicy = new AuthorizationPolicyBuilder(IdentityServerJwtConstants.IdentityServerJwtBearerScheme)
.RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(authorizationPolicy));
您可以使用这些链接阅读更多内容
我正在开发一个 blazor 应用程序,我在其中使用我的 API 项目作为标识
提供商。一切正常,但问题是访问令牌
由我的 API 发布,未被 API 验证。事实证明 API 期待
cookie header。我仔细查看了 blazor 托管应用程序并发现
cookie 随每个请求一起发送,但它是 same-origin。
我的 Blazor WASM 项目不会自动在请求中附加此 cookie
header,只是访问令牌。
有没有办法让 Http 处理程序在每个请求上附加此 cookie?
或者让 API 验证访问令牌而不是身份 cookie。
这是我在 API 项目
中的启动 class public static void AddIdentityServer(IServiceCollection services,IConfiguration configuration)
{
services.AddIdentityServer(options =>
{
options.UserInteraction.LoginUrl = "/Identity/Account/Login";
options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
}).AddProfileService<LocalProfileService>()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(option =>
{
option.Clients.Add(new Client
{
ClientId = "blazor",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
AllowedCorsOrigins = { "https://localhost:5001" },
AllowedScopes = { "openid", "profile", "email","id" },
RedirectUris = { "https://localhost:5001/authentication/login-callback" },
PostLogoutRedirectUris = { "https://localhost:5001/" },
Enabled = true,
RequireConsent = false,
});
option.IdentityResources.AddEmail();
option.IdentityResources["openid"].UserClaims.Add("name");
option.ApiResources.Single().UserClaims.Add("name");
option.IdentityResources["openid"].UserClaims.Add("role");
option.ApiResources.Single().UserClaims.Add("role");
option.IdentityResources.Add(new IdentityResource("id",new string[] {"id" }));
option.ApiResources.Single().UserClaims.Add("id");
});
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.ClientId = configuration["ExternalLoginApiKey:GoogleClientId"];
options.ClientSecret = configuration["ExternalLoginApiKey:GoogleClientSecret"];
})
.AddFacebook("Facebook", options =>
{
options.AppId = configuration["ExternalLoginApiKey:FacebookAppId"];
options.AppSecret = configuration["ExternalLoginApiKey:FacebookAppSecret"];
})
.AddIdentityServerJwt();
}
Blazor 项目中的程序 class
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = "role";
}).AddAccountClaimsPrincipalFactory<CustomUserFactory>();
builder.Services.AddHttpClient<IAuthorizedRestService, AuthorizedRestService>(
client => client.BaseAddress = new Uri("https://localhost:5002/api/mart/v1/"))
.AddHttpMessageHandler(sp => sp.GetRequiredService<AuthorizationMessageHandler>()
.ConfigureHandler(authorizedUrls: new[] { "https://localhost:5002" }));
builder.Services.AddHttpClient("noauth", option => option.BaseAddress = new
Uri("https://localhost:5002/api/mart/v1/"));
builder.Services.AddScoped<IRestService, RestService>();
await builder.Build().RunAsync();
}
我找到了解决方案。
碰巧 IdentityServer4 已经为兼作授权服务器的 API 提供了一个 JWT 处理程序
.AddIdentityServerJwt();
所以我所做的就是配置它
services.Configure<JwtBearerOptions>
(IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.Authority = "https://localhost:5002";
options.Audience = "mart";
options.SaveToken = true;
});
然后指定要使用的身份验证方案
[Authorize(AuthenticationSchemes = IdentityServerJwtConstants.IdentityServerJwtBearerScheme)]
也可以在启动时全局添加class
var authorizationPolicy = new AuthorizationPolicyBuilder(IdentityServerJwtConstants.IdentityServerJwtBearerScheme)
.RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(authorizationPolicy));
您可以使用这些链接阅读更多内容