ADFS 身份验证期间的间歇性重定向循环 [英] Intermittent redirection loops during ADFS authentication

查看:25
本文介绍了ADFS 身份验证期间的间歇性重定向循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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:

app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType);

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

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

我还有一个自定义身份验证过滤器(与 AuthorizeAttribute 结合使用):

I also have a custom authentication filter (used in conjunction with 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 登录之间会发生重定向循环.这似乎是特定于会话的(不会同时对所有用户发生),一旦发生重定向循环,它似乎会继续发生,直到应用程序池刷新.

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.

当重定向循环发生时,我仍然可以看到(在 Chrome 的网络"选项卡中)看起来像是由 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.

我很难找出根本原因,但我发现 - 当循环不发生时,user.Identity 的类型为 ClaimsIdentity并且 IsAuthenticatedtrue.当它确实发生时,IsAuthenticatedfalseuser.IdentityWindowsIdentity 类型>.

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.

IIS 中的所有身份验证形式(匿名除外)均已禁用.IIS Express 未在任何地方使用.

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

这可能是什么原因造成的?

What could be causing this?

推荐答案

您使用会话数据或 TempData 吗?我明白它与cookies有关.我也有同样的问题.

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

这里有一些更多信息和一个详细解释原因.该问题可以通过强制 Owin 使用 System.Web 的 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):

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()
})

这篇关于ADFS 身份验证期间的间歇性重定向循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆