WebAPI 使用 OIDC 身份验证处理程序为用户声明进行额外的访问
WebAPI making an extra trip for user claims using OIDC authentication handler
我当前的设置是:
我在端口 7025 使用 Duenede.IdentityServer 包 运行 构建了一个身份服务器。
我有一个基于 Dotnet 6 的 WebApi,下面是它的 OIDC 配置。
AddOpenIdConnect("oidc", o =>
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
o.SaveTokens = true;
o.GetClaimsFromUserInfoEndpoint = true;
o.RequireHttpsMetadata = false;
o.ResponseType = "code";
o.Authority = "https://localhost:7025/";
o.ClientId = "some clientid";
o.ClientSecret = "some secret";
o.Scope.Clear();
o.Scope.Add("openid");
o.Scope.Add("profile");
o.Scope.Add("dotnetapi");
o.NonceCookie.SameSite = SameSiteMode.Unspecified;
o.CorrelationCookie.SameSite = SameSiteMode.Unspecified;
o.ClaimActions.MapUniqueJsonKey("role", "role");
o.ClaimActions.MapUniqueJsonKey("email", "email");
});
现在,当网络 api 从身份服务器请求令牌时(OIDC 是质询方案,我将 cookie 方案设置为默认身份验证方案)它同时获得 id_token 和 access_token(使用 await HttpContext.GetTokenAsync("access_token");
await HttpContext.GetTokenAsync("id_token");
验证)。我还可以在 HttpContext.User.FindFirst("some claim");
中找到用户声明
但我注意到有一个从网络 api 到身份服务器的额外调用,用于用户信息。我观察到这可能是因为 o.GetClaimsFromUserInfoEndpoint = true;
当我省略此行时我发现未设置用户声明,即使我仍然获得 ID 和访问令牌。
所以我的理解是 dotnet 的 OIDC 客户端正在使用 userinfo 端点来获取用户声明。但我的问题是,如果我已经收到 access_token 为什么要额外调用用户信息。可以阻止这个额外的调用吗?
有什么方法可以让我首先收到 id_token,然后像现在这样获取 access_token,这样相同的信息就不会发送两次?
首先,您可以在 IdentityServer 中设置此客户端配置,以始终在 ID 令牌中包含用户声明
AlwaysIncludeUserClaimsInIdToken
When requesting both an id token and access token, should the user
claims always be added to the id token instead of requiring the client
to use the userinfo endpoint. Default is false.
不将它包含在 ID-token 中的原因是增加了 id-token 的大小,如果您将令牌存储在 asp.net 会话 cookie 中,它也可以成为挺大的。
我不会担心用户验证时发生的额外请求。
我当前的设置是:
我在端口 7025 使用 Duenede.IdentityServer 包 运行 构建了一个身份服务器。
我有一个基于 Dotnet 6 的 WebApi,下面是它的 OIDC 配置。
AddOpenIdConnect("oidc", o => { JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); o.SaveTokens = true; o.GetClaimsFromUserInfoEndpoint = true; o.RequireHttpsMetadata = false; o.ResponseType = "code"; o.Authority = "https://localhost:7025/"; o.ClientId = "some clientid"; o.ClientSecret = "some secret"; o.Scope.Clear(); o.Scope.Add("openid"); o.Scope.Add("profile"); o.Scope.Add("dotnetapi"); o.NonceCookie.SameSite = SameSiteMode.Unspecified; o.CorrelationCookie.SameSite = SameSiteMode.Unspecified; o.ClaimActions.MapUniqueJsonKey("role", "role"); o.ClaimActions.MapUniqueJsonKey("email", "email"); });
现在,当网络 api 从身份服务器请求令牌时(OIDC 是质询方案,我将 cookie 方案设置为默认身份验证方案)它同时获得 id_token 和 access_token(使用 await HttpContext.GetTokenAsync("access_token");
await HttpContext.GetTokenAsync("id_token");
验证)。我还可以在 HttpContext.User.FindFirst("some claim");
但我注意到有一个从网络 api 到身份服务器的额外调用,用于用户信息。我观察到这可能是因为 o.GetClaimsFromUserInfoEndpoint = true;
当我省略此行时我发现未设置用户声明,即使我仍然获得 ID 和访问令牌。
所以我的理解是 dotnet 的 OIDC 客户端正在使用 userinfo 端点来获取用户声明。但我的问题是,如果我已经收到 access_token 为什么要额外调用用户信息。可以阻止这个额外的调用吗?
有什么方法可以让我首先收到 id_token,然后像现在这样获取 access_token,这样相同的信息就不会发送两次?
首先,您可以在 IdentityServer 中设置此客户端配置,以始终在 ID 令牌中包含用户声明
AlwaysIncludeUserClaimsInIdToken
When requesting both an id token and access token, should the user claims always be added to the id token instead of requiring the client to use the userinfo endpoint. Default is false.
不将它包含在 ID-token 中的原因是增加了 id-token 的大小,如果您将令牌存储在 asp.net 会话 cookie 中,它也可以成为挺大的。
我不会担心用户验证时发生的额外请求。