ADFS认证期间出现间歇性重定向循环

12

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

app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType);

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

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

我还有一个自定义的身份验证过滤器(与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。当它发生时,IsAuthenticatedfalse,但user.Identity的类型是WindowsIdentity

IIS中除匿名以外的所有身份验证都已禁用。 IIS Express在任何地方都没有使用。

这可能是什么原因呢?

1个回答

21

你使用session数据和TempData吗?我了解这与cookies有关。我也遇到同样的问题。

这里提供了更多信息详细的原因解释。可以通过强制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<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),
            });
    }
}

然后进行连线:

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

谢谢你,你帮我省去了很多麻烦。有趣的是,我们也遇到了你的问题,但没有得到答案!希望你不介意,我已经扩展了你的答案,包括Katana bug的解决方法,这样人们就可以在链接失效时仍然能够使用它。我本来想添加自己的答案并附上额外信息,但我认为你应该得到任何荣誉。 - Ant P
我忘了我已经问过这个问题了,我最好去更新一下。我也实现了这个解决方案,目前为止还不错。 - Jamie
3
如果有人需要的话,提醒一下,CookieAuthenticationOptions.CookieManager 仅在 Microsoft.Owin.Security.Cookies v3.0.0 及以上版本中可用。请留意。 - Dunc
谢谢你的帮助。今天这仍然是一个问题,真是难以置信。我已经实施了你的解决方案,它运行得非常完美。最近我们不得不这样做,因为我们当前的实现突然停止工作了。太疯狂了! - Joshua H
到目前为止,这对我来说似乎是有效的,但在接下来的半个小时内,我会了解更多情况,因为每20-30分钟后,刷新web.config后AD FS错误似乎又出现了。感谢您提供的解决方案!祈求好运。 - Jamie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接