我正在使用identityserver3进行身份验证,使用OpenIDConnect。我注意到即使用户未经同意,IdentityServer3也会返回用户的个人资料信息。我不确定这个默认行为还是错误。当我使用EF和AspNetIdentity配置客户端,范围和用户时,就会发生这种情况。 这就是我配置IdentityServer的方式
用户
Properties
UserName: Someusername
Password: SomePassword
Email: user@domain.com
Phone:1234567
Claims:
Country: US
TimeZoneID: CST
范围(openid)
Name: openid
Enabled: true
Type: 0 ( ie. Identity)
客户端
AbsoluteRefreshTokenLifeTime: 300
AccessTokenLifeTime: 7200
ClientID: LocalHostMvcClient
Client Name: Local Host Client
Enabled: true
EnableLocalLoging: true
IdentityTokenLifetimne:300
PrefixClientClaims: true
RequireConsent:true
AllowAccessTokenViaBrowser:true
Scopes: openid
请注意,未添加profile
范围,这意味着客户端无法请求配置文件信息,因此用户无法同意配置文件信息。用户只能同意身份信息。
我已将客户端配置如下
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://localhost:44314/identity",
Scope = "openid",
ClientId = "LocalHostMvcClient",
RedirectUri = "http://localhost:34937/",
ResponseType = "id_token token",
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var nid = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
// get userinfo data
var userInfoClient = new UserInfoClient(
new Uri(n.Options.Authority + "/connect/userinfo"),
n.ProtocolMessage.AccessToken);
var userInfo = await userInfoClient.GetAsync();
userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2)));
n.AuthenticationTicket = new AuthenticationTicket(
nid,
n.AuthenticationTicket.Properties);
}
}
});
}
我原以为userInfoClient.GetAsync()
只会返回preferred_username
和sub
声明。然而,它也返回所有用户的个人资料信息。像phonenumber,email,Country和TimeZoneID。
我注意到只有在使用EF& S在SQL中配置用户,范围和客户端时才会发生这种情况。 AspNetIdentity。如果我在内存中配置
Update1 (根据Brock Allen发布的问题&#39>
public class UserService : AspNetIdentityUserService<User, string>
{
public UserService(UserManager userMgr)
: base(userMgr)
{
}
}
public class AspNetIdentityUserService<TUser, TKey> : UserServiceBase
where TUser : class, Microsoft.AspNet.Identity.IUser<TKey>, new()
where TKey : IEquatable<TKey>
{
..
..
..
..
public override async Task GetProfileDataAsync(ProfileDataRequestContext ctx)
{
var subject = ctx.Subject;
var requestedClaimTypes = ctx.RequestedClaimTypes;
if (subject == null) throw new ArgumentNullException("subject");
TKey key = ConvertSubjectToKey(subject.GetSubjectId());
var acct = await userManager.FindByIdAsync(key);
if (acct == null)
{
throw new ArgumentException("Invalid subject identifier");
}
var claims = await GetClaimsFromAccount(acct);
if (requestedClaimTypes != null && requestedClaimTypes.Any())
{
claims = claims.Where(x => requestedClaimTypes.Contains(x.Type));
}
ctx.IssuedClaims = claims;
}
}
UPDATE2
以下修复似乎对我有用。
public override async Task GetProfileDataAsync(ProfileDataRequestContext ctx)
{
var requestedClaimTypes = ctx.RequestedClaimTypes;
if (requestedClaimTypes != null && requestedClaimTypes.Any())
{
var subject = ctx.Subject;
if (subject == null) throw new ArgumentNullException("subject");
TKey key = ConvertSubjectToKey(subject.GetSubjectId());
var acct = await userManager.FindByIdAsync(key);
if (acct == null)
{
throw new ArgumentException("Invalid subject identifier");
}
var claims = await GetClaimsFromAccount(acct);
claims = claims.Where(x => requestedClaimTypes.Contains(x.Type));
ctx.IssuedClaims = claims;
}
}
但是,我还注意到了另外一个问题。在profile
范围内,即使我将IncludeAllCliamsForUser
设置为true
,仍然在GetProfileDataAsync
方法ctx.RequestedClaimTypes
中返回null。
因此,即使客户端请求profile
为了实现这一目标,除了上述修复之外,我还必须向profile
范围明确添加用户声明并将IncludeAllCliamsForUser
设置为false
答案 0 :(得分:0)
如果您的用户服务实施GetProfileData
未遵守RequestedClaimTypes
上下文参数,那么这就是泄漏的来源。也许这就是问题?