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

[英]Intermittent redirection loops during ADFS authentication


I am using Owin to configure my ASP.NET MVC 5 (.NET 4.5, IIS 7/8) application to authenticate against a third-party ADFS setup:

我正在使用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
});

I also have a custom authentication filter (used in conjunction with AuthorizeAttribute):

我还有一个自定义身份验证过滤器(与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)
    {
    }
}

This works fine half of the time but sometimes, on initial login, a redirect loop will occur between the app and the ADFS login. This seems to be session-specific (does not occur for all users at once) and once the redirect loop occurs it seems to continue occurring until an application pool refresh.

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

When the redirect loop occurs, I can still see (in Chrome's Network tab) what looks like a valid token being issued by ADFS.

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

I'm having a hard time isolating the root cause but what I have found is that - when the loop does not occur, user.Identity is of type ClaimsIdentity and IsAuthenticated is true. When it does occur, IsAuthenticated is false but user.Identity is of type WindowsIdentity.

我很难隔离根本原因,但我发现 - 当循环没有发生时,user.Identity的类型为ClaimsIdentity,IsAuthenticated为true。确实发生时,IsAuthenticated为false,但user.Identity的类型为WindowsIdentity。

All forms of authentication in IIS - except Anonymous - are disabled. IIS Express is not in use anywhere.

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

What could be causing this?

可能是什么导致了这个?

2 个解决方案

#1


14  

Do you use session data, and or TempData? I understand is it related to cookies. I too have the same issue.

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

Here is some more information and a thorough explanation of the cause. The problem can be worked around by forcing Owin to use System.Web's cookie pipeline (from here):

这里有一些更多的信息和对原因的详尽解释。可以通过强制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),
            });
    }
}

And to wire it up:

连线:

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

#2


0  

This is correct. Creating new cookie manager, rather than using existing one fixed the issue.

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

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

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

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2015/02/17/53198f82517a32b75dd64bd9f02ea273.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告