Blazor IdentityServer 身份验证
Posted
技术标签:
【中文标题】Blazor IdentityServer 身份验证【英文标题】:Blazor IdentityServer Authenthentication 【发布时间】:2021-04-22 02:22:36 【问题描述】:目前我有三个独立的服务器。客户端在:5001,API 在:5002 和 IdentityServer 在:5003。我可以使用@attribute [Authorize]
对我的 Blazor 页面进行身份验证,但是当我调用 API 时出现 401 错误。如果我将 token_id 传递给邮递员并向其验证的 API 服务器发出请求。如果我从 Blazor 客户端发出请求,它将失败。我已将 CORS 列入白名单以排除此问题。如果我通过以下方式删除 API 上的受众检查:
options.TokenValidationParameters = new TokenValidationParameters
ValidateAudience = false
;
有效
客户端程序.cs
builder.Services.AddHttpClient("api")
.AddHttpMessageHandler(sp =>
var handler = sp.GetService<AuthorizationMessageHandler>()
.ConfigureHandler(
authorizedUrls: new[] "https://localhost:5002" ,
scopes: new[] "coredesk" );
return handler;
);
builder.Services.AddScoped(
sp => sp.GetService<IHttpClientFactory>().CreateClient("api"));
builder.Services.AddOidcAuthentication(options =>
builder.Configuration.Bind("oidc", options.ProviderOptions);
);
客户端 appsettings.json
"oidc":
"Authority": "https://localhost:5003/",
"ClientId": "coredesk",
"DefaultScopes": [
"openid",
"profile",
"coredesk"
],
"PostLogoutRedirectUri": "/",
"ResponseType": "code"
API 启动.cs
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.Authority = "https://localhost:5003";
options.Audience = "coredesk";
);
IdentityServer Config.cs
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
;
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
new ApiResource("coredesk", "CoreDesk API")
;
public static IEnumerable<ApiScope> ApiScopes =>
new ApiScope[]
new ApiScope("coredesk"),
;
public static IEnumerable<Client> Clients =>
new Client[]
new Client
ClientId = "coredesk",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
AllowedCorsOrigins = "https://localhost:5001", "https://localhost:5002" ,
AllowedScopes = "openid", "profile", "coredesk" ,
RedirectUris = "https://localhost:5001/authentication/login-callback" ,
PostLogoutRedirectUris = "https://localhost:5001/" ,
Enabled = true
,
;
【问题讨论】:
当您收到 401 错误时,WWW-Authenticate 响应标头会说什么?错误示例如下所示:HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer error="invalid_token", error_description="签名无效" 如果我删除 api 中的 Authorize 属性并运行调试器。我遵循的 Microsoft 文档和指南并未显示您必须将 Token 添加到标题中。我认为这是因为您不会将令牌存储在浏览器中 medium.com/@marcodesanctis2/… 【参考方案1】:如果你查看AddJwtBearer 的源代码,你会发现这部分:
// If no authorization header found, nothing to process further
if (string.IsNullOrEmpty(authorization))
return AuthenticateResult.NoResult();
if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
token = authorization.Substring("Bearer ".Length).Trim();
// If no token found, no further work possible
if (string.IsNullOrEmpty(token))
return AuthenticateResult.NoResult();
这表明默认情况下(没有自定义)它需要在 Authorization 标头中提供令牌,如下所示:
GET /api/payments HTTP/1.1
Host: localhost:7001
Authorization: Bearer eyJhbGciOiJSUzI1NiIsIYwA...
为了进一步调试,我将删除授权属性,然后在其中一个操作方法中放置一个断点并检查 ClaimsPrincipal 用户对象包含的内容。
【讨论】:
肯定是拿到令牌了。我刚刚尝试删除 API 上的 Audience 检查,它可以工作。我很确定我不会从任何地方错过 coredesk 范围。 WWW-Authenticate 标头说什么?您还可以查看 API 中的日志,Kestrel 确实提供了大量好的日志。 请看这篇博文leastprivilege.com/2019/01/18/…以上是关于Blazor IdentityServer 身份验证的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Blazor WebAssembly 和 IdentityServer 4 配置持久登录?
Blazor 客户端中的 Identityserver4 未授权 api
Blazor WebAssembly+Duende.IdentityServer+EF Core认证授权企业级实战
如何通过 IdentityServer4 将 OpenId Connect 添加到 ASP.NET Core 服务器端 Blazor Web 应用程序?