太多的OpenID.noncecookie会导致"Bad Request"



我已经在这里,这里和这里都通过了与我有问题有关的链接。

我使用Silverlight应用程序使用denisterver3进行身份验证,并且当我实现登录功能时,我现在就开始遇到此问题。请注意,问题与Silverlight无关,因为登录和注销功能实际上是在服务器端实现的,这是经典的ASP.NET Web表单。(.NET 4.5.1)

该应用程序从未具有注销功能,因此用户只是用来关闭浏览器,因此我们以前从未遇到过此问题。现在,我们有logout.aspx页面和Silverlight应用程序已链接到此页面。

logout.aspx page

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);
        }
    }
} 

OWIN启动类配置OpenID连接

  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);
                },                    
            }

复制问题的步骤:

  1. i键入网站URL,将我重定向到IdentityServer3登录页。
  2. 我输入凭据并点击登录。
  3. 成功登录后重定向到网站,然后在那里单击注销。
  4. 我被记录成功。提琴手显示以下电话

    https://idsvr.mydomain.com/indentity/connect/endsession?id_token_hint=xxxxxxxxxxxxxxxxxhttps://idsvr.mydomain.com/indesity/logout?id=616dd9a4e4e4c6a555b0bb27faceb4df8ddhttps://idsvr.mydomain.com/indestity/connect/endsessioncallback?sid=xxxxxxx

  5. 我登陆https://idsvr.mydomain.com/indesity/logout?id=xxxxxxx page。

  6. 现在我关闭浏览器(此步骤很重要)
  7. 现在再次键入网站URL,将我重定向到Identity Server登录页面。(如步骤1)
  8. 我输入凭据并点击登录。
  9. 成功登录后,IdentityServer将发布到网站,网站创建AuthenticationTicket。但是,这里的HttpContext.Current.Request.IsAuthenticated是错误的,因此Default.aspx页面重定向到IdentityServer。我已经登录了,因此IndetityServer重定向到客户端网站,并且循环继续进行。

提琴手显示了从IdentityServer到网站的Default.aspx页面的几次往返行程。每个往返都会不断添加OpenIdConnect.nonce.OpenIdConnect cookie,最终由于最大请求大小,我会遇到不良请求错误。

因此,正如上述链接中所建议的,我在客户端应用程序中将Microsoft.Owin.Security.OpenIdConnect降级至3.0.0

但是,我仍然被困在连续循环中。唯一的区别是,它不会为每个往返添加新的OpenIdConnect.nonce.OpenIdConnect cookie。提琴手每次往返都只会显示一个饼干。但是HttpContext.Current.Request.IsAuthenticated仍然是错误的。所以我被卡在连续的循环中。

我在我的ASP.NET MVC应用程序上也有类似的问题。经过一番研究,我发现Microsoft的OWIN实现System.Web存在一个错误。在IIS上运行OWIN应用程序时使用的一个。如果我们使用新的OWIN身份验证处理使用ASP.NET MVC5。

该错误使Owin设定的Cookie在某些情况下神秘地消失了。

此中间件是该错误的修复程序。简单将其添加到任何cookie处理中间件之前,它将保留身份验证cookie。

app.UseKentorOwinCookieSaver();

这是详细的链接https://github.com/kentorit/owin-cookie-saver

我解决问题的方法是使用adamdotnet的自定义openIdConnectAuthenticationHandler删除旧的Nonce cookies。

https://stackoverflow.com/a/51671887/4058784

相关内容

  • 没有找到相关文章

最新更新