IdentityServer AspNetIdentity AspNetUserClaims 未在客户端上填充
IdentityServer AspNetIdentity AspNetUserClaims not populating on Client
我将 IdentityServer3 与 IdentityServer3.AspNetIdentity 使用 OpenId 客户端一起使用,我可以成功进行身份验证,但是 AspNetUserClaims table 中持有的声明未发送到客户端。 IdentityServer 配置为:
- 混合流
- 始终发送客户声明为真
- 范围:openid 配置文件电子邮件
我添加了一个基于 AspNetIdentityUserService 的自定义 class 并覆盖了 GetClaimsFromAccount 方法。我提供了与原始实现相同的实现 (https://github.com/IdentityServer/IdentityServer3.AspNetIdentity/blob/master/source/IdentityServer3.AspNetIdentity/IdentityServer3.AspNetIdentity.cs) 并设置了一个断点 - 我可以看到 AspNetUserClaims 中持有的所有声明,但是它们不包含在客户端的声明集合中。
我的客户端代码是:
OpenIdConnectAuthenticationOptions openIdConnectAuthenticationOptions = new OpenIdConnectAuthenticationOptions
{
//BackchannelTimeout = TimeSpan.FromMinutes(sessionTimeoutInMinutes),
ClientId = "xxx",
Authority = "https://xxx/core",
PostLogoutRedirectUri = "https://localhost:44304",
ResponseType = "code id_token token",
Scope = "openid profile email",
Notifications = new OpenIdConnectAuthenticationNotifications()
{
SecurityTokenValidated = async (context) =>
{
//string userId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
var id_token = context.ProtocolMessage.IdToken;
var abc = new JwtSecurityToken(id_token);
var def = abc.Claims;
List<Claim> claims = new List<Claim>();
UserInfoClient userInfoClient = new UserInfoClient(new Uri("https://shaves2u.azurewebsites.net/core/connect/userinfo"), context.ProtocolMessage.AccessToken);
var userInfo = await userInfoClient.GetAsync();
userInfo.Claims.ToList().ForEach(ui => claims.Add(new Claim(ui.Item1, ui.Item2)));
return;
//return Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl + "/";
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl + "/";
if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
Claim idTokenHint = context.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
context.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
},
AuthorizationCodeReceived = (context) =>
{
ClaimsIdentity identity = context.AuthenticationTicket.Identity;
identity.AddClaim(new Claim("id_token", context.ProtocolMessage.IdToken));
context.AuthenticationTicket = new Microsoft.Owin.Security.AuthenticationTicket(identity, context.AuthenticationTicket.Properties);
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
if (context.Exception.Message.StartsWith("OICE_20004") || context.Exception.Message.Contains("IDX10311"))
{
context.SkipToNextMiddleware();
return Task.FromResult(0);
}
return Task.FromResult(0);
}
}
};
来自代码 abc.Claims 不包含来自 AspNetUserClaims 的任何声明,也不包含 userInfo.Claims。
有人可以帮忙吗?
对于遇到同样问题的其他人,我想分享我的解决方案。最后,这被证明是一个配置设置。将范围的 IncludeAllClaimsForUser 设置为 true。我为我的应用程序创建了一个新范围,但是在配置文件范围上设置此 属性 也应该有效。
我将 IdentityServer3 与 IdentityServer3.AspNetIdentity 使用 OpenId 客户端一起使用,我可以成功进行身份验证,但是 AspNetUserClaims table 中持有的声明未发送到客户端。 IdentityServer 配置为:
- 混合流
- 始终发送客户声明为真
- 范围:openid 配置文件电子邮件
我添加了一个基于 AspNetIdentityUserService 的自定义 class 并覆盖了 GetClaimsFromAccount 方法。我提供了与原始实现相同的实现 (https://github.com/IdentityServer/IdentityServer3.AspNetIdentity/blob/master/source/IdentityServer3.AspNetIdentity/IdentityServer3.AspNetIdentity.cs) 并设置了一个断点 - 我可以看到 AspNetUserClaims 中持有的所有声明,但是它们不包含在客户端的声明集合中。
我的客户端代码是:
OpenIdConnectAuthenticationOptions openIdConnectAuthenticationOptions = new OpenIdConnectAuthenticationOptions
{
//BackchannelTimeout = TimeSpan.FromMinutes(sessionTimeoutInMinutes),
ClientId = "xxx",
Authority = "https://xxx/core",
PostLogoutRedirectUri = "https://localhost:44304",
ResponseType = "code id_token token",
Scope = "openid profile email",
Notifications = new OpenIdConnectAuthenticationNotifications()
{
SecurityTokenValidated = async (context) =>
{
//string userId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
var id_token = context.ProtocolMessage.IdToken;
var abc = new JwtSecurityToken(id_token);
var def = abc.Claims;
List<Claim> claims = new List<Claim>();
UserInfoClient userInfoClient = new UserInfoClient(new Uri("https://shaves2u.azurewebsites.net/core/connect/userinfo"), context.ProtocolMessage.AccessToken);
var userInfo = await userInfoClient.GetAsync();
userInfo.Claims.ToList().ForEach(ui => claims.Add(new Claim(ui.Item1, ui.Item2)));
return;
//return Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl + "/";
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl + "/";
if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
Claim idTokenHint = context.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
context.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
},
AuthorizationCodeReceived = (context) =>
{
ClaimsIdentity identity = context.AuthenticationTicket.Identity;
identity.AddClaim(new Claim("id_token", context.ProtocolMessage.IdToken));
context.AuthenticationTicket = new Microsoft.Owin.Security.AuthenticationTicket(identity, context.AuthenticationTicket.Properties);
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
if (context.Exception.Message.StartsWith("OICE_20004") || context.Exception.Message.Contains("IDX10311"))
{
context.SkipToNextMiddleware();
return Task.FromResult(0);
}
return Task.FromResult(0);
}
}
};
来自代码 abc.Claims 不包含来自 AspNetUserClaims 的任何声明,也不包含 userInfo.Claims。
有人可以帮忙吗?
对于遇到同样问题的其他人,我想分享我的解决方案。最后,这被证明是一个配置设置。将范围的 IncludeAllClaimsForUser 设置为 true。我为我的应用程序创建了一个新范围,但是在配置文件范围上设置此 属性 也应该有效。