【发布时间】:2017-08-01 11:26:10
【问题描述】:
我已经浏览了与我遇到的问题相关的链接 here、here 和 here。
我有使用 IdentiServer3 进行身份验证的 Silverlight 应用程序,我刚刚在实现注销功能时开始遇到此问题。请注意,该问题与 Silverlight 无关,因为登录和注销功能实际上是在服务器端实现的,这是一个经典的 ASP.Net Web 表单。 (.NET 4.5.1)
该应用程序从未具有注销功能,因此用户只是习惯于关闭浏览器,因此我们以前从未遇到过此问题。我们现在有 logout.aspx 页面,Silverlight 应用程序有指向该页面的链接。
Logout.aspx 页面
public partial class Logout : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
Session.Clear();
Request.GetOwinContext().Authentication.SignOut();
}
Response.Redirect("/");
}
}
Default.aspx 页面。这是起始页
public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Send an OpenID Connect sign-in request.
if (!System.Web.HttpContext.Current.Request.IsAuthenticated)
{
HttpContext.Current.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
}
配置OpenID连接的OWIN启动类
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
LoginPath = new Microsoft.Owin.PathString("/Default.aspx")
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = ConfigurationManager.AppSettings["Authority"],
Scope = "openid profile",
ClientId = ConfigurationManager.AppSettings["ClientId"],
RedirectUri = ConfigurationManager.AppSettings["RedirectUri"],
ResponseType = "id_token",
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = (context) =>
{
var id = context.AuthenticationTicket.Identity;
// create new identity
var newIdentity = new ClaimsIdentity(id.AuthenticationType);
// we want to keep username and subjectid
var sub = id.FindFirst(ClaimTypes.NameIdentifier);
var username = id.FindFirst("preferred_username");
newIdentity.AddClaim(username);
newIdentity.AddClaim(sub);
// keep the id_token for logout
newIdentity.AddClaim(new Claim("id_token", context.ProtocolMessage.IdToken));
context.AuthenticationTicket = new AuthenticationTicket(
newIdentity,
context.AuthenticationTicket.Properties);
return Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var idTokenHint = context.OwinContext.Authentication.User.FindFirst("id_token").Value;
context.ProtocolMessage.IdTokenHint = idTokenHint;
}
return Task.FromResult(0);
},
}
重现问题的步骤:
- 我输入网站 URL,将我重定向到 identityserver3 登录 页。
- 我输入凭据并点击登录。
- 登录成功后我 被重定向到网站,然后我点击注销。
-
我被登录了 顺利出局。 Fiddler 显示以下调用
https://idsvr.mydomain.com/identity/connect/endsession?id_token_hint=XXXXXXXXXXXXXX https://idsvr.mydomain.com/identity/logout?id=616dd9a4e4c6a55b0bb27faceb4df8dd https://idsvr.mydomain.com/identity/connect/endsessioncallback?sid=xxxxxx
我按预期登陆了https://idsvr.mydomain.com/identity/logout?id=xxxxxxx页面。
- 现在我关闭浏览器(这一步很重要)
- 现在再次输入网站 URL,将我重定向到身份服务器登录页面。 (如第 1 步)
- 我输入凭据并点击登录。
- 成功登录后,IdentityServer 向网站进行 POST,网站创建 AuthenticationTicket。然而,这里
HttpContext.Current.Request.IsAuthenticated是假的,所以Default.aspx页面重定向到IdentityServer。我已经登录,因此 Indetityserver 重定向到客户端网站并继续循环。
Fiddler 展示了从 identityServer 到网站的 default.aspx 页面的多次往返。每次往返都会不断添加OpenIdConnect.nonce.OpenIdConnect cookie,最终由于最大请求大小而出现错误的请求错误。
因此,正如上述链接中所建议的,我在客户端应用程序中将 Microsoft.Owin.Security.OpenIdConnect 降级为 3.0.0。
但是,我仍然陷入连续循环。唯一的区别是现在它不会为每次往返添加新的OpenIdConnect.nonce.OpenIdConnect cookie。 Fiddler 每次往返仅显示一个 cookie。但是HttpContext.Current.Request.IsAuthenticated 仍然是错误的。所以我陷入了连续循环。
【问题讨论】:
-
有时会出现死循环,当客户端使用http,但服务器使用https(或相反)。见stackoverflow.com/questions/29780627/…
-
你解决了吗?
-
@bkwdesign 是的,我通过添加github.com/KentorIT/owin-cookie-saver 中间件解决了它。
标签: c# asp.net-identity owin identityserver3 openid-connect