我正在考虑如何断开当前登录mvc客户端的用户(例如http://localhost:5001),当该用户在身份服务器的部署上执行注销时(例如http://localhost:5000)
据我所知,identityserver4中有一个OAuth2的实现,可以实现(https://openid.net/specs/openid-connect-backchannel-1_0.html和https://openid.net/specs/openid-connect-frontchannel-1_0.html)
幸运的是,Brock Allen在不到一天前推出了样品的变化:https://github.com/IdentityServer/IdentityServer4.Samples/issues/197
然而此时样本不完整,或者我遗漏了一些东西。
在我的服务器上,我将FrontChannelLogoutUrl的值设置为http://localhost:5001/frontchannello,然后我将这段代码添加到我的mvc客户端(基本上是从示例中窃取的):
[HttpGet("frontChannello")]
public IActionResult FrontChannelLogout(string sid)
{
if (User.Identity.IsAuthenticated)
{
var currentSid = User.FindFirst("sid")?.Value ?? "";
if (string.Equals(currentSid, sid, StringComparison.Ordinal))
{
//await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return new SignOutResult(new[] { "Cookies", "oidc" });
}
}
return NoContent();
}
该代码永远不会被调用。
所以我的问题是:我应该使用backchannel还是前端频道;以及如何实施
答案 0 :(得分:1)
好的很简单。在帐户控制器(在idserver中)的“注销”操作中,确保显示LoggedOut视图,该视图又显示在mvc客户端上调用回调的iFrame。几乎是规范所说的。
答案 1 :(得分:0)
Identity server 4 documentation很好地描述了如何实现前通道注销。寻找快速入门8_AspnetIdentity,因为它提供了实现所需的大多数代码。
身份服务器中所需代码的一些重点:
在AccountController.cs
中,注销功能将构建一个LoggedOutViewModel
并返回一个LoggedOut
视图。
[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); ... return View("LoggedOut", vm); }
SignOutIframeUrl iframe在LoggedOut.cshtml
中提供。
@model LoggedOutViewModel <div class="page-header logged-out"> <small>You are now logged out</small> ... @if (Model.SignOutIframeUrl != null) { <iframe width="0" height="0" class="signout" src="@Model.SignOutIframeUrl"></iframe> } </div>
剩下要做的就是为每个客户定义FrontChannelLogoutUri
。这通常是在身份服务器的config.cs
public static IEnumerable<Client> GetClients() { return new List<Client> { // resource owner password grant client new Client { ClientId = "js", ClientName = "JavaScript Client", AllowedGrantTypes = GrantTypes.Code, RequirePkce = true, RequireClientSecret = false, RedirectUris = { "http://localhost:5003/callback.html" }, PostLogoutRedirectUris = { "http://localhost:5003/index.html" }, FrontChannelLogoutUri = "http://localhost:5003/frontChannello"