问题描述
我使用 IdentityServer4 和 .Net Core Signin Manager 创建了一个 OAuth 服务器。登录效果很好并返回到我的应用程序。注销似乎不知道谁在注销。退出 Razor 页面代码如下:
public async Task<IActionResult> OnGet(string logoutId)
{
var logout = await _interaction.GetlogoutContextAsync(logoutId);
PostlogoutRedirectUri = logout?.PostlogoutRedirectUri;
AutomaticRedirectAfterSignOut = (PostlogoutRedirectUri != null);
ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName;
SignOutIframeUrl = logout?.SignOutIFrameUrl;
logoutId = logoutId;
if (User?.Identity.IsAuthenticated == true)
{
var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;
if (idp != null && idp != IdentityServer4.IdentityServerConstants.LocalIdentityProvider)
{
var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);
if (providerSupportsSignout)
{
if (logoutId == null)
{
// if there's no current logout context,we need to create one
// this captures necessary info from the current logged in user
// before we signout and redirect away to the external IdP for signout
logoutId = await _interaction.CreatelogoutContextAsync();
}
ExternalAuthenticationScheme = idp;
}
}
// delete local authentication cookie
await _signInManager.SignOutAsync();
// raise the logout event
await _events.RaiseAsync(new UserlogoutSuccessEvent(User.GetSubjectId(),User.GetdisplayName()));
}
// check if we need to trigger sign-out at an upstream identity provider
if (TriggerExternalSignout)
{
// build a return URL so the upstream provider will redirect back
// to us after the user has logged out. this allows us to then
// complete our single sign-out processing.
string url = Url.Action("logout",new { logoutId = logoutId });
// this triggers a redirect to the external provider for sign-out
return SignOut(new AuthenticationProperties { RedirectUri = url },ExternalAuthenticationScheme);
}
if (AutomaticRedirectAfterSignOut)
return Redirect(PostlogoutRedirectUri);
else
return Page();
}
当它被调用时,有一个 logoutId。它获取上下文,但 PostlogoutRedirectUri 为空。 ClientId 和 ClientName 也为空,但上下文有一个名为 ClientIds 的字段,第一个条目是我的应用程序的正确 ClientId。日志显示如下:
IdentityServer4.Validation.EndSessionRequestValidator: information: End session request validation success
{
"SubjectId": "6841dc6c-0bd7-4f72-8f1c-f7czzzzzzzzz","Raw": {
"post_logout_redirect_uri": "mps.mobile.app://callback"
}
}
IdentityServer4.Hosting.IdentityServerMiddleware: information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.EndSessionCallbackEndpoint for /connect/endsession/callback
IdentityServer4.Endpoints.EndSessionCallbackEndpoint: information: Successful signout callback.
我正在为客户端应用程序使用 IdentityModel。我的注销编码如下:
_options = new OidcclientOptions
{
Authority = MPSOidc.Authority,ClientId = MPSOidc.ClientID,Scope = "openid profile myapi offline_access email",RedirectUri = MPSOidc.RedirectUri,PostlogoutRedirectUri = MPSOidc.RedirectUri,ResponseMode = OidcclientOptions.AuthorizeResponseMode.Redirect,browser = new ChromeCustomTabsbrowser(this)
};
var oidcclient = new Oidcclient(_options);
var r = new logoutRequest();
await oidcclient.logoutAsync(r);
似乎 PostlogoutRedirectUri 应该出现在这里。有谁知道一种方法来实现这一目标?如果没有,是否可以通过ClientId 获取Client 信息以找到其中的PostlogoutRedirectUri?
谢谢, 吉姆
解决方法
原来是这样。当我在 OidcClient 上注销时,我没有传递 ID 令牌。在我的客户端 Android 应用程序上,我必须将 ID 令牌添加到注销请求中:
var r = new LogoutRequest()
{
IdTokenHint = MPSOidc.Tokens.IdentityToken
};
这就是全部。 干杯。