我想在通过IdSrv进行身份验证时检索的访问令牌中默认包含声明。声明Ticket
应始终包含在访问令牌中,因此我创建了一个作为资源范围的新范围,并将Ticket
包含为ScopeClaim
。但是,当IdSrv创建访问令牌并调用GetProfileDataAsync
时,您可以从IdSrv日志中看到,上下文中请求的声明列表为空,因此不会向访问令牌添加任何声明。
默认情况下,如何将此声明包含在访问令牌中?
我的印象是,请求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();
}
网络配置
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
答案 0 :(得分:1)
更新2:现在好了,我看得更近了,你有IncludeAllClaimsForUser = true
。在GetProfileData中,上下文中有一个可比较的标志。我怀疑这就是为什么你没有在集合中提出任何要求。
更新1:您希望加入代币的声明应添加到GetProfile
中,而不是AuthenticateResult
方法中的AuthentivcateLocal
。
原文:将范围类型从Identity
更改为Resource
。这会影响索赔所涉及的令牌。