2016-04-22 113 views
11

我在OpenOID Connect身份驗證(Microsoft.Owin.Security.OpenIdConnect)中使用OWIN/OAuth在C#ASP MVC Web應用程序中。使用Microsoft帳戶的SSO登錄基本上可行,但有時我會在瀏覽器上看到一個錯誤頁面,內容爲Bad Request - Request Too Long太多cookie OpenIdConnect.nonce導致錯誤頁面「錯誤請求 - 請求太長」

我發現這個錯誤是由太多的cookie引起的。刪除Cookie有助於一段時間,但過了一段時間問題又回來了。

導致問題的cookies是從OpenId框架設置的,所以有幾十個名字如OpenIdConnect.nonce.9oEtF53WxOi2uAw.......的cookie。

這不是SPA應用程序,但是某些部分會使用ajax調用定期刷新。

回答

25

事實證明,根本原因是Ajax調用。

有問題的流量爲

1)OAuth的餅乾得到了一些時間

2)到期通常會導致重定向的頁面login.microsoft.com刷新餅乾後到期。在此步驟中,OAuth框架爲響應添加了新的nonce cookie(每次)!

3)但Ajax不處理域外的重定向(跨域到login.microsoft.com)。但該cookie已被附加到頁面上。

4)下一次週期性的Ajax調用重複導致'nonce'cookie快速增加的流程。

解決方案

我不得不延長「OWIN的OpenID」框架設置代碼來處理Ajax調用不同 - 防止重定向和停止發送的cookie。

public void ConfigureAuth(IAppBuilder app) 
{ 
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 
    app.UseCookieAuthentication(new CookieAuthenticationOptions()); 

    app.UseOpenIdConnectAuthentication(
     new OpenIdConnectAuthenticationOptions 
     { 
      ClientId = clientId, 
      Authority = authority, 
      Notifications = new OpenIdConnectAuthenticationNotifications 
      { 
       RedirectToIdentityProvider = ctx => 
       { 
        bool isAjaxRequest = (ctx.Request.Headers != null && ctx.Request.Headers["X-Requested-With"] == "XMLHttpRequest"); 

        if (isAjaxRequest) 
        { 
         ctx.Response.Headers.Remove("Set-Cookie"); 
         ctx.State = NotificationResultState.HandledResponse; 
        } 

        return Task.FromResult(0); 
       } 
      } 
     }); 
} 

阿賈克斯主叫方不得不調整過檢測401代碼並執行刷新整個頁面(這引起了快速重定向到微軟授權)。

+1

謝謝。我遇到了類似的問題,這有助於解決問題。 – Namrehs

+0

這也似乎解決了我的問題,一旦我清除鉻餅乾。具有諷刺意味的MS的勇敢的新瀏覽器邊緣....具有與IE一樣多的不一致和性能問題,所以我現在回到使用鉻。 –

+0

解決了我的問題。謝謝 –

0

在我的情況下,問題是我在Startup.cs中配置應用程序的順序。

提醒自己 - 總是首先配置認證!

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 
     app.UseCookieAuthentication(new CookieAuthenticationOptions()); 
     app.UseOpenIdConnectAuthentication(
      new OpenIdConnectAuthenticationOptions 
      { 
       ClientId = _clientId, 
       ClientSecret = _clientSecret, 
       Authority = _authority, 
       RedirectUri = _redirectUri 
      }); 

     // configure the rest of the application... 
    } 
相關問題