2015-02-17 13 views
9

Sto usando Owin configurare il mio ASP.NET MVC 5 (.NET 4.5, IIS 7/8) applicazione per l'autenticazione con una terza parte ADFS setup:reindirizzamento intermittente loop durante l'autenticazione ADFS

app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType); 

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType 
}); 

app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions 
{ 
    Wtrealm = Settings.Auth.Wtrealm, 
    MetadataAddress = Settings.Auth.MetadataAddress 
}); 

I hanno anche un filtro di autenticazione personalizzato (utilizzato in combinazione con AuthorizeAttribute):

public class OwinAuthenticationAttribute : ActionFilterAttribute, IAuthenticationFilter 
{ 
    public void OnAuthentication(AuthenticationContext filterContext) 
    { 
     var user = filterContext.RequestContext.HttpContext.User; 

     var authenticated = user.Identity.IsAuthenticated; 
     if (!authenticated) 
     { 
      return; 
     } 

     /* Redirect to profile setup if not already complete */ 
    } 

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) 
    { 
    } 
} 

Questo funziona bene la metà del tempo, ma a volte, il login iniziale, si verificherà un loop di reindirizzamento tra l'applicazione e il login ADFS. Questo sembra essere specifico per la sessione (non si verifica per tutti gli utenti contemporaneamente) e una volta che il ciclo di reindirizzamento si verifica sembra continuare a verificarsi fino a quando un pool di applicazioni si aggiorna.

Quando si verifica il ciclo di reindirizzamento, posso ancora vedere (nella scheda Rete di Chrome) ciò che sembra un token valido emesso da ADFS.

Sto attraversando un periodo difficile isolare la causa principale, ma quello che ho trovato è che - quando il ciclo non si verifica, user.Identity è di tipo ClaimsIdentity e IsAuthenticated è true. Quando si verifica , IsAuthenticated è false ma user.Identity è di tipo WindowsIdentity.

Tutte le forme di autenticazione in IIS, ad eccezione di Anonymous, sono disabilitate. IIS Express non è in uso da nessuna parte.

Cosa potrebbe causare questo?

risposta

12

Usi i dati di sessione e/o TempData? Capisco è relativo ai cookie. Anch'io ho lo stesso problema.

Ecco alcuni more information e uno thorough explanation of the cause. Il problema può essere aggirato forzando Owin di utilizzare gasdotto di System.Web biscotto (da here):

public class SystemWebCookieManager : ICookieManager 
{ 
    public string GetRequestCookie(IOwinContext context, string key) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException("context"); 
     } 

     var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 
     var cookie = webContext.Request.Cookies[key]; 
     return cookie == null ? null : cookie.Value; 
    } 

    public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException("context"); 
     } 
     if (options == null) 
     { 
      throw new ArgumentNullException("options"); 
     } 

     var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 

     bool domainHasValue = !string.IsNullOrEmpty(options.Domain); 
     bool pathHasValue = !string.IsNullOrEmpty(options.Path); 
     bool expiresHasValue = options.Expires.HasValue; 

     var cookie = new HttpCookie(key, value); 
     if (domainHasValue) 
     { 
      cookie.Domain = options.Domain; 
     } 
     if (pathHasValue) 
     { 
      cookie.Path = options.Path; 
     } 
     if (expiresHasValue) 
     { 
      cookie.Expires = options.Expires.Value; 
     } 
     if (options.Secure) 
     { 
      cookie.Secure = true; 
     } 
     if (options.HttpOnly) 
     { 
      cookie.HttpOnly = true; 
     } 

     webContext.Response.AppendCookie(cookie); 
    } 

    public void DeleteCookie(IOwinContext context, string key, CookieOptions options) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException("context"); 
     } 
     if (options == null) 
     { 
      throw new ArgumentNullException("options"); 
     } 

     AppendResponseCookie(
      context, 
      key, 
      string.Empty, 
      new CookieOptions 
      { 
       Path = options.Path, 
       Domain = options.Domain, 
       Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), 
      }); 
    } 
} 

E per legare in su:

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    // ... 
    CookieManager = new SystemWebCookieManager() 
}) 
+0

Grazie per questo - mi hai salvato un sacco di mal di testa. Stranamente abbiamo trovato la tua domanda su questo, ma non è stata data risposta! Spero non ti dispiaccia, ma ho esteso la tua risposta per includere la soluzione alternativa al bug di Katana, in modo che le persone possano ancora ottenerlo se il collegamento si interrompe. Stavo per aggiungere la mia risposta con queste informazioni aggiuntive, ma penso che ti meriti qualsiasi merito. –

+0

Mi ero dimenticato di averlo già chiesto, è meglio che vada ad aggiornarlo. Ho anche implementato questa soluzione e finora tutto bene. – Jamie

+2

Se salva qualcun altro, 'CookieAuthenticationOptions.CookieManager' è disponibile solo da [Microsoft.Owin.Security.Cookies] (https://www.nuget.org/packages/Microsoft.Owin.Security.Cookies) v3. 0.0 in poi – Dunc

Problemi correlati