我有一台运行Identity Server 4的Identity Server。注销代码类似于他们在其sample project中建议的代码。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout(LogoutInputModel model)
{
// build a model so the logged out page knows what to display
var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);
if (User?.Identity.IsAuthenticated == true)
{
// delete local authentication cookie
await HttpContext.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 (vm.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 = vm.LogoutId });
// this triggers a redirect to the external provider for sign-out
return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);
}
return View("LoggedOut", vm);
}
上面的代码的作用是在删除身份服务器上的登录cookie来注销之前。
await HttpContext.SignOutAsync();
这一切造就了完美的感觉。在身份服务器上。有人致电注销并注销。
第三方申请
我的问题是与第三方应用程序有关。当我们的第三方应用程序调用注销时,它们将调用身份服务器,它会删除cookie并将注销返回给应用程序。但是,那并不是真的在做什么。它注销了所有人。
如果我们有三个第三方应用程序,其中一个已注销,则它们都将被注销,因为它的身份服务器已注销,而不仅仅是第三方应用程序。
例如,我知道Google不允许第三方注销。我目前正在使用我的Google帐户登录到SO,如果我退出该帐户,那只会使我退出SO,而不是Google,而我的所有其他应用程序都已登录Google。
所以我的问题是我如何防止第三方应用程序注销每个人并仍然允许他们注销自己?
我尝试过的事情
我尝试进行检查,以确保调用注销的应用程序是我们的第三方应用程序之一,只是不删除cookie。那没有用,因为他们的应用程序只是再次检查身份服务器,并说它仍在登录,因此有必要注销第三方应用程序,仅在用户请求时才重新登录。我曾考虑过删除用户同意书,但这不会起作用,因为他们下次登录时必须再次授予同意书。
我的想法
我考虑告诉第三方开发人员,他们需要一个带有登录按钮的虚拟视图,以便用户不得不单击该按钮,而不是感谢他们直接链接到身份服务器上的登录。我认为这种解决方案在开发人员中不会很受欢迎。