【发布时间】:2018-03-06 18:25:53
【问题描述】:
当用户在某些情况下注销时,我想在已注销的页面上向他们显示一条消息。要启用此功能,我希望能够在注销时将可选参数从客户端发送到身份服务器/授权站点。
虽然我的标准注销流程正常工作,但我在处理这种情况时遇到了困难,因为信息似乎很少,建议的解决方案不起作用。
根据我的阅读,“状态”参数是传递此信息的正确方法,但目前还没有通过。 AcrValues 仅用于以其他方式发送信息。
我下面的简单实现只是将状态查询字符串项添加到结束会话端点。但是,当我检查我的客户端用于访问身份服务器实例的查询字符串时,它丢失了。
重定向(discoveryResponse.EndSessionEndpoint+"&state=foo")
很高兴收到任何帮助!
MVC 客户端的当前流程:
请注意;为简洁起见,一些代码已被删除。
从带有 state=foo 的客户端控制器发起的注销:
public class LogoutController : Controller
{
public ActionResult Index()
{
Request.GetOwinContext().Authentication.SignOut();
var discoveryClient = new DiscoveryClient(clientConfig.Authority) { Policy = {RequireHttps = false} };
var discoveryResponse = discoveryClient.GetAsync().Result;
var tokenClaim = ((ClaimsIdentity)User.Identity).FindFirst("id_token");
return Redirect(discoveryResponse.EndSessionEndpoint+ "?id_token_hint="+ tokenClaim + "&state=foo");
}
}
为请求调用 RedirectToIdentityProvider:
IdTokenHint 和 PostLogoutRedirectUri 已正确设置和传递。
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType != OpenIdConnectRequestType.LogoutRequest)
return Task.FromResult(0);
var idTokenHint = n.OwinContext.Authentication.User.FindFirst(OpenIdConnectClaimType.IdToken);
if (idTokenHint == null) return Task.FromResult(0);
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
n.OwinContext.Response.Cookies.Append("IdentityServerPostLogoutReturnUri",
n.ProtocolMessage.PostLogoutRedirectUri);
n.ProtocolMessage.PostLogoutRedirectUri =
n.Options.PostLogoutRedirectUri;
return Task.FromResult(0);
}
}
已生成 URL(不是缺少“状态”项):
权威网站的登出页面:
这是我希望能够访问状态参数的地方。
public class LogoutController : Controller
{
public async Task<ViewResult> Index(string logoutId)
{
if (logoutId == null) throw new Exception("Missing logoutId");
var logoutRequest = await interactionService.GetLogoutContextAsync(logoutId);
var vm = new LoggedOutViewModel(logoutRequest, logoutId);
if (!string.IsNullOrWhiteSpace(httpContextService.GetCookieValue(PostLogoutReturnUriCookieKey)))
{
vm.PostLogoutRedirectUri = httpContextService.GetCookieValue(PostLogoutReturnUriCookieKey);
httpContextService.ClearCookie(PostLogoutReturnUriCookieKey);
}
await httpContextService.SignOutAsync();
return View("Index", vm);
}
}
【问题讨论】:
-
状态参数是为了客户的利益,应该对 IDP 不透明。我认为您需要在客户端应用程序的注销后处理程序中选择它。至于为什么没有在您的重定向中传递状态参数,我想这与该中间件处理程序有关。
-
感谢 Mackie,您对中间件问题的看法是正确的。
标签: c# asp.net-mvc authentication openid-connect identityserver4