OpenIDConnectを使用した認証にidentityserver3を使用しています。ユーザーが同意していなくてもIdentityServer3がユーザーのプロファイル情報を返すことに気付きました。このデフォルトの動作かバグかどうかはわかりません。 EFとAspNetIdentityを使ってクライアント、スコープ、ユーザーを設定したときの状況です。 これは私がIdentityServerIdentityServer3はユーザーの同意なしにユーザープロファイル情報を返します
ユーザーの構成方法である
Properties
UserName: Someusername
Password: SomePassword
Email: [email protected]
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
スコープが追加されていないことに注意してください。クライアントがプロファイル情報を要求できないため、ユーザーはプロファイル情報に同意できません。ユーザーは身元情報のみに同意することができます。
は私がuserInfoClient.GetAsync()
だけpreferred_username
とsub
主張を返します。期待していた
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);
}
}
});
}
以下のようにクライアントを設定しています。ただし、すべてのユーザーのプロファイル情報も戻します。 phonenumber、email、Country、TimeZoneIDと同様です。 EF & AspNetIdentityを使用してSQLでユーザー、スコープおよびクライアントを構成した場合にのみ、この現象が発生していることに気付きました。私はメモリに設定されている場合、私はこの出来事を見ていない
アップデート1
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;
}
}
アップデート2次修正がのために働いているようだ
(問題以下のBrockアレンの返信あたりなど)私。
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;
}
}
しかし、私ももう1つの問題に気付きました。私がIncludeAllCliamsForUser
をtrue
に設定しても、profile
スコープでは、まだGetProfileDataAsync
の方法ctx.RequestedClaimTypes
が返されます。
だから、のUserInfoエンドポイントは、クライアントがこの作業を取得するにはprofile
を要求している場合でも、上記の修正に加えて、私はまた、明示的profile
スコープにユーザーのクレームを追加する必要がありますし、false
'https:// identityserver.github.io/Documentation/docsv2/endpoints/userinfo.html' UserInfoエンドポイントのドキュメントでは、「UserInfoエンドポイントを使用してサブジェクトに関するID情報を取得できます。少なくとも「openid」スコープを持つ有効なアクセストークンが必要です。 – LP13
上記のupdate1を参照してください。これは現在の実装です。 'requestedClaimTypes'がnullの場合、すべてのClaimsを返します。 – LP13