IdentityServer3在未经用户同意的情况下返回用户个人资料信息

时间:2016-07-20 20:23:36

标签: identityserver3

我正在使用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范围,这意味着客户端无法请求配置文件信息,因此用户无法同意配置文件信息。用户只能同意身份信息。

Here is SQL Storage

我已将客户端配置如下

    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_usernamesub声明。然而,它也返回所有用户的个人资料信息。像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

,UserInfo端点也不会返回任何声明

为了实现这一目标,除了上述修复之外,我还必须向profile范围明确添加用户声明并将IncludeAllCliamsForUser设置为false

1 个答案:

答案 0 :(得分:0)

如果您的用户服务实施GetProfileData未遵守RequestedClaimTypes上下文参数,那么这就是泄漏的来源。也许这就是问题?