2016-04-22 22 views
11

Używam OWIN/OAuth z uwierzytelnianiem OpenId Connect (Microsoft.Owin.Security.OpenIdConnect) w aplikacji sieci web M # C# ASP. Logowanie logowania jednokrotnego z kontem Microsoft zasadniczo działa, ale od czasu do czasu otrzymuję stronę z błędem w przeglądarce, która mówi: Bad Request - Request Too Long.Zbyt wiele ciasteczek OpenIdConnect.nonce powoduje stronę błędu "Złe żądanie - żądanie zbyt długo"

Okazało się, że ten błąd jest spowodowany zbyt dużą liczbą plików cookie. Usuwanie plików cookie pomaga przez pewien czas, ale po pewnym czasie problem powraca.

Pliki cookie, które powodują problem, są ustawiane z frameworku OpenId, więc istnieją dziesiątki plików cookie o nazwach takich jak OpenIdConnect.nonce.9oEtF53WxOi2uAw........

To nie jest aplikacja SPA, ale niektóre części są okresowo odświeżane za pomocą wywołań ajax.

Odpowiedz

25

Okazało się, że główną przyczyną była rozmowa Ajax.

Problematyczny przepływu wynosiła

1) OAuth ciasteczko ale wygasł po pewnym czasie

2) Wygaśnięcie zazwyczaj powoduje przekierowanie do strony login.microsoft.com aby odświeżyć cookie. W tym kroku framework OAuth dodaje do odpowiedzi nowy plik cookienonce (za każdym razem)!

3) Ale Ajax nie obsługuje przekierowań poza domenę (między domenami do login.microsoft.com). Ale plik cookie został już dołączony do strony.

4) Następna okresowa rozmowa Ajax powtórzyła przepływ, powodując szybki wzrost liczby ciasteczek "nonce".

Rozwiązanie

Musiałem przedłużyć „OWIN OpenID” kod instalacyjny ramy do obsługi Ajax nazywa się inaczej - aby zapobiec przekierowanie i zatrzymać wysyłanie plików 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); 
       } 
      } 
     }); 
} 

Ajax rozmówca należało dostosować również do wykrywania kodu 401 i wykonać pełne odświeżania strony (co spowodowało szybki przekierowanie do organu Microsoft).

+1

Dziękuję. Miałem podobny problem, który pomógł go rozwiązać. – Namrehs

+0

To również pojawiło się, aby rozwiązać mój problem po wyczyszczeniu ciasteczek chrome. Jak na ironię, nowa dzielna przeglądarka MS Edge ... ma tyle samo niespójności i problemów z wydajnością, co IE, więc wracam do korzystania z Chrome na razie. –

+0

Rozwiązał również mój problem. Dzięki –

0

W moim przypadku problemem była kolejność, w jakiej konfigurowałem aplikację wewnątrz Startup.cs.

Przypomnienie na siebie - zawsze najpierw konfiguruj uwierzytelnianie!

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... 
    }