2015-02-17 18 views
9

używam Owin skonfigurować moje ASP.NET MVC 5 (.NET 4.5, IIS 7/8) Zastosowanie do uwierzytelnienia wobec osób trzecich ADFS Setup:Przerywany przekierowanie pętli podczas uwierzytelniania 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 również filtr uwierzytelniania użytkowego (stosowany w połączeniu z 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) 
    { 
    } 
} 

ten działa dobrze w połowie czasu, ale czasami początkowego logowania pętla przekierowanie nastąpi między aplikacją i logowania ADFS. Wydaje się, że jest to zależne od sesji (nie występuje jednocześnie dla wszystkich użytkowników) i po uruchomieniu pętli przekierowania wydaje się, że nadal występuje, dopóki nie zostanie odświeżona pula aplikacji.

Gdy pojawi się pętla przekierowania, nadal widzę (na karcie Sieć w Chrome), co wygląda na prawidłowy token wydany przez program ADFS.

Mam twardy czas izolować przyczyny, ale co znalazłem to, że - gdy pętla nie występuje, user.Identity jest typu ClaimsIdentity i IsAuthenticated jest true. Gdy występuje , występuje, IsAuthenticated jest false, ale user.Identity jest typu WindowsIdentity.

Wszystkie formy uwierzytelniania w IIS - z wyjątkiem anonimowego - są wyłączone. Usługi IIS Express nie są używane nigdzie.

Co może być przyczyną?

Odpowiedz

12

Czy używasz danych sesji i lub TempData? Rozumiem, że jest to związane z plikami cookie. Też mam ten sam problem.

Oto niektóre more information i thorough explanation of the cause. Problem ten można obejść poprzez zmuszanie Owin używać cookies rurociągu system.Web za (od 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), 
      }); 
    } 
} 

I drut go:

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

Thanks for this - zapisaniu mi dużo bólu głowy. Co zabawne, natknęliśmy się na twoje pytanie na ten temat, ale nie było odpowiedzi! Mam nadzieję, że nie masz nic przeciwko, ale rozszerzyłem twoją odpowiedź o obejście tego błędu z Katany, żeby ludzie mogli się do niego dostać, jeśli link kiedykolwiek umrze. Zamierzałem dodać własną odpowiedź z tymi dodatkowymi informacjami, ale myślę, że zasługujesz na jakąkolwiek zasługę. –

+0

Zapomniałem, że już o to pytałem, lepiej idę i aktualizuję. Wdrożyłem również to rozwiązanie i jak na razie dobrze. – Jamie

+2

W przypadku, gdy komenda ta zostanie zapisana innym osobom, "CookieAuthenticationOptions.CookieManager" jest dostępny tylko w [Microsoft.Owin.Security.Cookies] (https://www.nuget.org/packages/Microsoft.Owin.Security.Cookies) v3. 0.0 od – Dunc

Powiązane problemy