IdSrvを使用して認証するときに取得されるアクセストークンに、デフォルトでクレームを含める必要があります。要求Ticket
は常にリソーストークンである新しいスコープを作成したため、Ticket
をScopeClaim
として含むアクセストークンに含める必要があります。 IdSrvがアクセストークンを作成しているときにIdSrvログから確認できるように、GetProfileDataAsync
を呼び出すと、コンテキスト内で要求されたクレームのリストが空になり、アクセストークンにクレームが追加されなくなります。認可エンドポイントから取得したアクセストークンにクレームを含めるにはどうすればよいですか?
このクレームをデフォルトでアクセストークンに含めるにはどうすればよいですか?
私は、Resource
スコープを要求すると、スコープ内のクレームをアクセストークンの一部として返すことができるという印象を受けました。
スコープ
public static List<Scope> Get()
{
return new List<Scope>
{
StandardScopes.OpenId //standard scope when dealing with open id connect
,
StandardScopes.OfflineAccess
,
new Scope
{
Name = "App",
DisplayName = "App",
Type = ScopeType.Identity,
Claims = new List<ScopeClaim>
{
new ScopeClaim
{
AlwaysIncludeInIdToken = false,
Name = "App",
Description = "Role Information"
},
// new ScopeClaim
// {
// AlwaysIncludeInIdToken = false,
// Name = "Ticket",
// Description = "Login ticket"
// }
},
IncludeAllClaimsForUser = false
},
new Scope
{
Name = "AppAccess",
DisplayName = "AppAccess",
Type = ScopeType.Resource,
Claims = new List<ScopeClaim>
{
new ScopeClaim
{
Name = "Ticket",
Description = "Login ticket",
}
},
IncludeAllClaimsForUser = true
}
};
請求
public static List<Client> Get()
{
return new List<Client>
{
new Client
{
ClientName = "Hybrid Flow",
ClientId = "apphybrid",
Enabled = true,
Flow = Flows.Hybrid,
AllowAccessToAllScopes = true,
IdentityTokenLifetime = 120,
AccessTokenLifetime = 400,
RequireConsent = false,
ClientSecrets = new List<Secret>
{
new Secret("secret".Sha256())
},
RedirectUris = new List<string>
{
"localhost/App/login/Login.mr"
},
PostLogoutRedirectUris = new List<string>
{
"localhost/App/login/Login.mr"
},
AllowedScopes = new List<string>
{
Constants.StandardScopes.OpenId,
Constants.StandardScopes.OfflineAccess,
"App",
"AppAccess"
}
}
};
}
IDSrv構成
public override Task AuthenticateLocalAsync(LocalAuthenticationContext context)
{
var securityServiceProxy = new SecurityServiceProxy(new ServiceHeadersParameters { UserHostAddress = Ctx.Request.Host.Value });
var ticket = securityServiceProxy.UseServiceClient(serviceClient => serviceClient.AuthenticateUser(context.UserName, context.Password, Configuration.ProviderCode));
if (!ticket.IsValid())
{
context.AuthenticateResult = new AuthenticateResult("Invalid credentials");
return Task.FromResult(0);
}
var claims = new List<Claim> {
new Claim(GlobalConstant.TicketClaim, ticket.Ticket.ToString())
};
context.AuthenticateResult = new AuthenticateResult(
ticket.UserObjId.ToString(),
context.UserName,
claims: claims,
authenticationMethod: Constants.AuthenticationMethods.Password,
identityProvider: Configuration.ProviderCode
);
return Task.FromResult(0);
}
public override Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var applicationDto = GetApplicationDto(context);
var claims = new List<Claim>
{
new Claim(Constants.ClaimTypes.Subject, context.Subject.GetSubjectId()),
};
Log.Debug("The requested claims...");
if (context.RequestedClaimTypes == null)
{
Log.Debug("Requested Claims is null");
}
else
{
foreach (var x in context.RequestedClaimTypes)
{
Log.Debug($"Claims {x}");
}
if (context.RequestedClaimTypes.Contains(GlobalConstant.TicketClaim))
claims.Add(context.Subject.Claims.Where(x => x.Type.Equals(GlobalConstant.TicketClaim)).FirstOrDefault());
if (context.RequestedClaimTypes.Contains(GlobalConstant.ApplicationClaim))
claims.Add(new Claim(GlobalConstant.ApplicationClaim, applicationDto.Jsonify()));
}
// set the issued claims - these are the ones that were requested, if available
context.IssuedClaims = claims;
Log.Debug("Finished ProfileDataAsync");
return Task.FromResult(0);
}
private ApplicationDto GetApplicationDto(ProfileDataRequestContext context)
{
var securityServiceProxy = new SecurityServiceProxy(new ServiceHeadersParameters { UserHostAddress = Ctx.Request.Host.Value });
return securityServiceProxy.UseServiceClient(serviceClient => serviceClient.RetrieveAuthenticatedUser(GetUserTicketFromContext(context)));
}
private static UserTicketDto GetUserTicketFromContext(ProfileDataRequestContext context)
{
Log.Debug("The claims in the context...");
foreach(var x in context.Subject.Claims)
{
Log.Debug($"Cliams {x.Type} {x.Value}");
}
var ticketString = context.Subject.Claims.Where(x => x.Type.Equals(GlobalConstant.TicketClaim)).FirstOrDefault()?.Value;
var userIdString = context.Subject.GetSubjectId();
Guid Ticket, UserId;
if(Guid.TryParse(ticketString, out Ticket) && Guid.TryParse(userIdString, out UserId))
{
return new UserTicketDto { Ticket = Ticket, UserObjId = UserId };
}
return new UserTicketDto();
}
Web構成
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
AntiForgeryConfig.UniqueClaimTypeIdentifier = IdentityModel.JwtClaimTypes.Name;
app.Use(async (ctx, next) => { await next(); });
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = OAuthConstant.Client,
RedirectUri = "localhost/App/login/Login.mr",
PostLogoutRedirectUri = "localhost/App/login/Login.mr",
Authority = "localhost/Oauth2server/securetoken",
SignInAsAuthenticationType = "Cookies",
ResponseType = "token code id_token",
Scope = "OpenId App offline_access AppAccess",
ClientSecret = "secret",
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthorizationCodeReceived = IdentityServerClient.HandleOther,
SecurityTokenReceived = IdentityServerClient.HandleOther,
MessageReceived = IdentityServerClient.HandleOther,
AuthenticationFailed = IdentityServerClient.HandleOther,
RedirectToIdentityProvider = IdentityServerClient.HandleRedirectToIdentityProvider,
SecurityTokenValidated = IdentityServerClient.HandleSecurityTokenValidated
}
});
のログ
2016-06-15 12:04:51.943 -05:00 [Information] Login page submitted
2016-06-15 12:04:55.320 -05:00 [Information] Login credentials successfully validated by user service
2016-06-15 12:04:55.332 -05:00 [Information] Calling PostAuthenticateAsync on the user service
2016-06-15 12:04:55.338 -05:00 [Information] issuing primary signin cookie
2016-06-15 12:04:55.344 -05:00 [Information] redirecting to: http://localhost/OAuth2Server/securetoken/connect/authorize?client_id=apphybrid&redirect_uri=http:%2F%2Flocalhost%2Fapp%2FLogin%2FLogin.mr&response_mode=form_post&response_type=code id_token token&scope=App openid offline_access AppAccess&state=OpenIdConnect.AuthenticationProperties%3DebxFcJnjMiMq2m1gPqBsYlrBWdLct2kaJSYn-s0nxImnff-37i4t8Wa3wAJewJGFe9msgeeqJDKtR1gwwfA0e8Pdd6RNAi6YPo_CqT4l5zV8ifohYQVN9TrWfLXITXuKId9IW2cCeRQL6d8uWfkzSANqAGSbSGJYZ5pgOLULQresbAiJ7N77FgBmgrVtX4hDQuwGGL5vZFCb_C5tjl8_ezH12w8zQfifKuLwjaDmOSGYyo2AqpowQXXeSSSDgKBF&nonce=636016067018002117.MWY4MGVjOWItYTFjYS00MTVlLTg4MDYtMjYxYjkwMWEzNzU4ZWViNzEyNTQtMjE0Mi00MjYzLTk2ZjMtODdhYmIxYTM5Mjg5
2016-06-15 12:04:55.368 -05:00 [Debug] Incoming request: /securetoken/connect/authorize
2016-06-15 12:04:55.381 -05:00 [Information] Start authorize request
2016-06-15 12:04:55.381 -05:00 [Information] Start authorize request protocol validation
2016-06-15 12:04:55.381 -05:00 [Information] "Authorize request validation success"
"{
\"ClientId\": \"apphybrid\",
\"ClientName\": \"app Hybrid Flow\",
\"RedirectUri\": \"http://localhost/app/Login/Login.mr\",
\"AllowedRedirectUris\": [
\"http://localhost/app/Login/Login.mr\"
],
\"SubjectId\": \"783bf872-b864-4042-853d-04fbcb7a505a\",
\"ResponseType\": \"code id_token token\",
\"ResponseMode\": \"form_post\",
\"Flow\": \"Hybrid\",
\"RequestedScopes\": \"app openid offline_access appAccess\",
\"State\": \"OpenIdConnect.AuthenticationProperties=ebxFcJnjMiMq2m1gPqBsYlrBWdLct2kaJSYn-s0nxImnff-37i4t8Wa3wAJewJGFe9msgeeqJDKtR1gwwfA0e8Pdd6RNAi6YPo_CqT4l5zV8ifohYQVN9TrWfLXITXuKId9IW2cCeRQL6d8uWfkzSANqAGSbSGJYZ5pgOLULQresbAiJ7N77FgBmgrVtX4hDQuwGGL5vZFCb_C5tjl8_ezH12w8zQfifKuLwjaDmOSGYyo2AqpowQXXeSSSDgKBF\",
\"Nonce\": \"636016067018002117.MWY4MGVjOWItYTFjYS00MTVlLTg4MDYtMjYxYjkwMWEzNzU4ZWViNzEyNTQtMjE0Mi00MjYzLTk2ZjMtODdhYmIxYTM5Mjg5\",
\"SessionId\": \"e79cd97a339b4513b45038e7755c1b88\",
\"Raw\": {
\"client_id\": \"apphybrid\",
\"redirect_uri\": \"http://localhost/app/Login/Login.mr\",
\"response_mode\": \"form_post\",
\"response_type\": \"code id_token token\",
\"scope\": \"app openid offline_access appAccess\",
\"state\": \"OpenIdConnect.AuthenticationProperties=ebxFcJnjMiMq2m1gPqBsYlrBWdLct2kaJSYn-s0nxImnff-37i4t8Wa3wAJewJGFe9msgeeqJDKtR1gwwfA0e8Pdd6RNAi6YPo_CqT4l5zV8ifohYQVN9TrWfLXITXuKId9IW2cCeRQL6d8uWfkzSANqAGSbSGJYZ5pgOLULQresbAiJ7N77FgBmgrVtX4hDQuwGGL5vZFCb_C5tjl8_ezH12w8zQfifKuLwjaDmOSGYyo2AqpowQXXeSSSDgKBF\",
\"nonce\": \"636016067018002117.MWY4MGVjOWItYTFjYS00MTVlLTg4MDYtMjYxYjkwMWEzNzU4ZWViNzEyNTQtMjE0Mi00MjYzLTk2ZjMtODdhYmIxYTM5Mjg5\"
}
}"
2016-06-15 12:04:55.399 -05:00 [Information] Creating Hybrid Flow response.
2016-06-15 12:04:55.412 -05:00 [Information] Creating Implicit Flow response.
2016-06-15 12:04:55.416 -05:00 [Debug] Creating access token
2016-06-15 12:04:55.424 -05:00 [Debug] Getting ProfileDataAsync
2016-06-15 12:04:55.436 -05:00 [Debug] The claims in the context...
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams sub 783bf872-b864-4042-853d-04fbcb7a505a
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams name dev.guser
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams amr password
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams idp IDSRV
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams auth_time 1466010295
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams ticket fc05cd84-7756-4ec5-ac3c-53ac6d4d5e2a
2016-06-15 12:04:55.975 -05:00 [Debug] The requseted claims...
2016-06-15 12:04:55.976 -05:00 [Debug] Requested Claims Is Null
2016-06-15 12:04:55.976 -05:00 [Debug] Finished ProfileDataAsync
2016-06-15 12:04:55.982 -05:00 [Debug] Creating JWT access token
2016-06-15 12:04:56.049 -05:00 [Debug] Creating identity token
2016-06-15 12:04:56.054 -05:00 [Information] Getting claims for identity token for subject: 783bf872-b864-4042-853d-04fbcb7a505a
2016-06-15 12:04:56.054 -05:00 [Debug] Getting ProfileDataAsync
2016-06-15 12:04:56.066 -05:00 [Debug] The claims in the context...
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams sub 783bf872-b864-4042-853d-04fbcb7a505a
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams name dev.guser
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams amr password
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams idp IDSRV
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams auth_time 1466010295
2016-06-15 12:04:56.066 -05:00 [Debug] Cliams ticket fc05cd84-7756-4ec5-ac3c-53ac6d4d5e2a
2016-06-15 12:04:56.338 -05:00 [Debug] The requseted claims...
2016-06-15 12:04:56.338 -05:00 [Debug] Cliams sub
2016-06-15 12:04:56.338 -05:00 [Debug] Finished ProfileDataAsync
2016-06-15 12:04:56.338 -05:00 [Debug] Creating JWT identity token
2016-06-15 12:04:56.344 -05:00 [Debug] Adding client "apphybrid" to client list cookie for subject "783bf872-b864-4042-853d-04fbcb7a505a"
2016-06-15 12:04:56.349 -05:00 [Information] End authorize request
2016-06-15 12:04:56.352 -05:00 [Information] Posting to http://localhost/app/Login/Login.mr
2016-06-15 12:04:56.352 -05:00 [Debug] Using AssetManager to render authorization response HTML
2016-06-15 12:04:56.388 -05:00 [Debug] Incoming request: /securetoken/assets/app.FormPostResponse.js
//Web
2016-06-15 12:04:56,422 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Triggered MessageReceivedNotification`2 notification
2016-06-15 12:04:56,426 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Triggered SecurityTokenReceivedNotification`2 notification
2016-06-15 12:04:56,487 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Triggered SecurityTokenValidated notification
2016-06-15 12:04:56,487 [16] DEBUG app.Web.IdentityServer.IdentityServerClient The Claims in the identity
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: iss http://localhost/OAuth2Server/securetoken
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: aud apphybrid
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: exp 1466010416
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: nbf 1466010296
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: nonce 636016067018002117.MWY4MGVjOWItYTFjYS00MTVlLTg4MDYtMjYxYjkwMWEzNzU4ZWViNzEyNTQtMjE0Mi00MjYzLTk2ZjMtODdhYmIxYTM5Mjg5
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: iat 1466010296
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: at_hash 6pIu3P1cEeTQJMcK8Gcnhw
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: c_hash VsSw9HC0xyodlSkSCZefLw
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: sid e79cd97a339b4513b45038e7755c1b88
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: sub 783bf872-b864-4042-853d-04fbcb7a505a
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: auth_time 1466010295
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: idp IDSRV
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Claims: amr password
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient The access token: [Omitted]
2016-06-15 12:04:56,488 [16] DEBUG app.Web.IdentityServer.IdentityServerClient The id token: [Omitted]
2016-06-15 12:04:56,491 [16] DEBUG app.Web.IdentityServer.IdentityServerClient Triggered AuthenticationFailedNotification`2 notification
//Web
//Logs
問題のログ出力...
2016-06-15 12:04:55.412 -05:00 [Information] Creating Implicit Flow response.
2016-06-15 12:04:55.416 -05:00 [Debug] Creating access token
2016-06-15 12:04:55.424 -05:00 [Debug] Getting ProfileDataAsync
2016-06-15 12:04:55.436 -05:00 [Debug] The claims in the context...
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams sub 783bf872-b864-4042-853d-04fbcb7a505a
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams name dev.guser
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams amr password
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams idp IDSRV
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams auth_time 1466010295
2016-06-15 12:04:55.437 -05:00 [Debug] Cliams ticket fc05cd84-7756-4ec5-ac3c-53ac6d4d5e2a <- Has the claim I want
2016-06-15 12:04:55.975 -05:00 [Debug] The requseted claims...
2016-06-15 12:04:55.976 -05:00 [Debug] Requested Claims Is Null <- but this needs to indicate that we want that claim...
2016-06-15 12:04:55.976 -05:00 [Debug] Finished ProfileDataAsync
スコープタイプは 'AppAccess'スコープの' Resource'です –
ああ、私はAppスコープを見ていました。 –
おそらく質問に答えるように更新されました。 –