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

问题描述

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

<$p$p><$c$c>app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType);app.UseCookieAuthentication(新CookieAuthenticationOptions{    AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType});app.UseWsFederationAuthentication(新WsFederationAuthenticationOptions{    Wtrealm = Settings.Auth.Wtrealm,    MetadataAddress = Settings.Auth.MetadataAddress});

我也有一个自定义的验证过滤器(结合使用 AuthorizeAttribute ):

 公共类OwinAuthenticationAttribute:ActionFilterAttribute,IAuthenticationFilter
{
    公共无效OnAuthentication(AuthenticationContext filterContext)
    {
        VAR用户= filterContext.RequestContext.HttpContext.User;

        VAR认证= user.Identity.IsAuthenticated;
        如果(!验证)
        {
            返回;
        }

        / *重定向到配置文件设置如果尚未完成* /
    }

    公共无效OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
    {
    }
}
 

该作品的时间细一半,但有时候,在初始登录时,重定向循环将应用程序和ADFS登录之间发生。这似乎是会话特定的(不会出现所有用户一次),一旦重定向循环出现似乎将继续发生,直到应用程序池刷新。

在重定向循环时,我仍然可以看到(在Chrome的网络选项卡)看起来像由ADFS所签发的有​​效标记。

我有一个很难隔离的根本原因,但我发现是 - 当循环不会发生, user.Identity 的类型是<$的C $ C> ClaimsIdentity 和 IsAuthenticated 。当它的确实的出现, IsAuthenticated ,但用户。身份的类型是的WindowsIdentity

验证在IIS中的所有形式 - 除了匿名 - 将被禁用。的IIS实施例preSS是在不使用任何地方。

什么引起的?

解决方案

您是否使用会话数据,并或TempData的?我的理解是它涉及到的cookies。我也有同样的问题。

下面是一些更多信息和的的/stackoverflow.com/a/21234614/1043198">thorough解释。这个问题可以通过周围的强制Owin使用的System.Web的cookie管道(从这里被工作>)

 公共类SystemWebCookieManager:ICookieManager
{
    公共字符串GetRequestCookie(IOwinContext背景下,字符串键)
    {
        如果(背景== NULL)
        {
            抛出新ArgumentNullException(上下文);
        }

        VAR webContext = context.Get&LT; HttpContextBase&GT;(typeof运算(HttpContextBase).FullName);
        VAR饼干= webContext.Request.Cookies [关键];
        返回cookie的== NULL?空:cookie.Value;
    }

    公共无效AppendResponseCookie(IOwinContext背景下,字符串键,字符串值,CookieOptions选项)
    {
        如果(背景== NULL)
        {
            抛出新ArgumentNullException(上下文);
        }
        如果(选择== NULL)
        {
            抛出新ArgumentNullException(选项);
        }

        VAR webContext = context.Get&LT; HttpContextBase&GT;(typeof运算(HttpContextBase).FullName);

        布尔domainHasValue = string.IsNullOrEmpty(options.Domain)!;
        布尔pathHasValue = string.IsNullOrEmpty(options.Path)!;
        布尔expiresHasValue = options.Expires.HasValue;

        VAR饼干=新的HttpCookie(键,值);
        如果(domainHasValue)
        {
            cookie.Domain = options.Domain;
        }
        如果(pathHasValue)
        {
            cookie.Path = options.Path;
        }
        如果(expiresHasValue)
        {
            cookie.Expires = options.Expires.Value;
        }
        如果(options.Secure)
        {
            cookie.Secure = TRUE;
        }
        如果(options.HttpOnly)
        {
            cookie.HttpOnly = TRUE;
        }

        webContext.Response.AppendCookie(饼干);
    }

    公共无效DeleteCookie(IOwinContext背景下,串键,CookieOptions选项)
    {
        如果(背景== NULL)
        {
            抛出新ArgumentNullException(上下文);
        }
        如果(选择== NULL)
        {
            抛出新ArgumentNullException(选项);
        }

        AppendResponseCookie(
            的背景下,
            键,
            的String.Empty,
            新CookieOptions
            {
                路径= options.Path,
                域= options.Domain,
                期满=新日期时间(1970年,1,1,0,0,0,DateTimeKind.Utc),
            });
    }
}
 

和接线起来:

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

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

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

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.

When the redirect loop occurs, I can still see (in Chrome's Network tab) what looks like a valid token being issued by 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.

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

What could be causing this?

解决方案

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

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),
            });
    }
}

And to wire it up:

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

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

08-22 15:57