我正在使用 Okta、.NET 6 和 Identity Server 4(正在说服高层管理人员从 4.0 升级到 6.0)。
我需要
id_token
才能从 Okta 注销,但它始终是 null
。
以下方法来自我自定义的
OpenIdConnectEvents
类:
在这里,我保留了令牌,以便它在
OnTicketReceivedImpl
事件中可用:
private Task OnTokenResponseReceivedImpl(TokenResponseReceivedContext context)
{
context.Properties?.StoreTokens(new[]
{
new AuthenticationToken
{
Name = "id_token",
Value = context.TokenEndpointResponse.IdToken
}
});
return Task.CompletedTask;
}
这里我添加声明:
private Task OnTicketReceivedImpl(TicketReceivedContext context)
{
var idToken = context.Properties?.Items[".Token.id_token"];
if (idToken != null)
{
((ClaimsIdentity)context.Principal?.Identity)?.AddClaim(new Claim("id_token", idToken));
}
return Task.CompletedTask;
}
您可以看到
id_token
已添加到Claims
中:
但是,当我尝试在注销期间访问
id_token
时,它是null
:
private Task OnRedirectToIdentityProviderForSignOutImpl(RedirectContext context)
{
var oidcMessage = context.ProtocolMessage;
// Which one of these methods should I use?
var idTokenClaim1 = context.HttpContext.User.FindFirst("id_token"); // null
var idTokenClaim = context.Properties.GetTokenValue("id_token"); // null
if (idTokenClaim != null)
{
oidcMessage.IdTokenHint = idTokenClaim;
oidcMessage.PostLogoutRedirectUri = HomeUrl.AbsoluteUri;
}
...
}
在这里您可以看到没有
id_token
声明,但添加了一个名为 idp
的声明,其值为 "local"
。
这是我的
Startup.ConfigureServices()
:
services.AddAuthentication()
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) // "Cookies"
.AddOpenIdConnect("oidc", "OpenIdConnect", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; // "idsrv.external"
options.SignOutScheme = IdentityServerConstants.SignoutScheme; // "idsrv"
options.Authority = "https://saas.oktapreview.com";
options.ClientId = "clientIdHere";
options.ClientSecret = "secretHere";
options.ResponseType = "code";
options.Scope.Add("email");
options.Scope.Add("phone");
options.Events = new IrmOpenIdConnectEvents();
options.SaveTokens = true;
});
退出时如何访问
id_token
?