web-dev-qa-db-fra.com

Trop de cookies OpenIdConnect. La cause d'erreur "Requête incorrecte - Demande trop longue"

J'utilise OWIN/OAuth avec l'authentification OpenId Connect (Microsoft.Owin.Security.OpenIdConnect) dans une application Web C # ASP MVC. La connexion SSO avec un compte Microsoft fonctionne à la base, mais de temps en temps, le navigateur affiche une page d'erreur indiquant Bad Request - Request Too Long.

J'ai découvert que cette erreur est causée par trop de cookies. La suppression des cookies est utile pendant un certain temps, mais le problème revient après un certain temps.

Les cookies à l'origine du problème sont définis à partir du cadre OpenId. Il existe donc des dizaines de cookies portant des noms tels que OpenIdConnect.nonce.9oEtF53WxOi2uAw........

Ce n'est pas une application SPA, mais certaines parties sont actualisées périodiquement avec des appels ajax.

14
andrew.fox

Il s’est avéré que la cause fondamentale était l’appel Ajax. 

Le flux problématique était

1) Le cookie OAuth a expiré après un certain temps 

2) L’expiration entraîne normalement la redirection de la page vers login.Microsoft.com afin d’actualiser le cookie. Dans cette étape, OAuth framework ajoute un nouveau cookie nonce à la réponse (à chaque fois)! 

3) Mais Ajax ne gère pas les redirections hors du domaine (cross-domain to login.Microsoft.com). Mais le cookie a déjà été ajouté à la page.

4) Le prochain appel périodique Ajax a répété le flux, ce qui a entraîné une augmentation rapide du nombre de cookies «nonce».

Solution

J'ai dû étendre le code de configuration du cadre "OWIN OpenId" pour gérer les appels Ajax différemment - pour empêcher la redirection et arrêter l'envoi de cookies. 

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

L'appelant Ajax a également dû être ajusté pour détecter le code 401 et effectuer l'actualisation complète de la page (ce qui a entraîné une redirection rapide vers l'autorité Microsoft).

36
andrew.fox

Dans mon cas, le problème était l’ordre dans lequel je configurais l’application dans Startup.cs.

Rappel à l'auto - configurez toujours l'authentification en premier!

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