ADFS身份validation期间的间歇重定向循环

我正在使用Owin配置我的ASP.NET MVC 5(.NET 4.5,IIS 7/8)应用程序以对第三方ADFS设置进行身份validation:

app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType }); app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions { Wtrealm = Settings.Auth.Wtrealm, MetadataAddress = Settings.Auth.MetadataAddress }); 

我还有一个自定义身份validationfilter(与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) { } } 

这种方法在一半的时间内工作正常,但有时,在初始登录时,应用程序和ADFS登录之间将发生重定向循环。 这似乎是特定于会话的(并非所有用户同时发生),并且一旦发生重定向循环,它似乎会继续发生,直到应用程序池刷新。

当重定向循环发生时,我仍然可以看到(在Chrome的“网络”标签中)看起来像ADFS发出的有效令牌。

我很难隔离根本原因,但我发现 – 当循环没有发生时, user.Identity的类型为ClaimsIdentityIsAuthenticatedtrue确实发生时, IsAuthenticatedfalseuser.Identity的类型为WindowsIdentity

IIS中的所有forms的身份validation(匿名除外)都被禁用。 IIS Express在任何地方都没有使用。

可能是什么导致了这个?

您是否使用会话数据和/或TempData? 我理解它与cookie有关。 我也有同样的问题。

这里有一些更多的信息和对原因的详尽解释 。 可以通过强制Owin使用System.Web的cookie管道(从这里 )来解决这个问题:

 public class SystemWebCookieManager : ICookieManager { public string GetRequestCookie(IOwinContext context, string key) { if (context == null) { throw new ArgumentNullException("context"); } var webContext = context.Get(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(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), }); } } 

连线:

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

这是对的。 创建新的cookie管理器,而不是使用现有的管理器来解决问题。

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