Периодические циклы перенаправления во время аутентификации ADFS

Я использую 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 Network), что похоже на действительный токен, выдаваемый ADFS.

Мне трудно выделить основную причину, но я обнаружил, что когда цикл не происходит, user.Identity имеет тип ClaimsIdentity а также IsAuthenticated является true, Когда это произойдет, IsAuthenticated является false но user.Identity имеет тип WindowsIdentity,

Все формы аутентификации в IIS, кроме Anonymous, отключены. IIS Express нигде не используется.

Что может быть причиной этого?

2 ответа

Решение

Используете ли вы данные сеанса, или TempData? Я понимаю, это связано с куки. У меня тоже такая же проблема.

Вот еще немного информации и подробное объяснение причины. Эту проблему можно обойти, заставив Овина использовать конвейер cookie System.Web ( отсюда):

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

Это правильно. Создание нового менеджера файлов cookie вместо использования существующего устранило проблему.

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

Другие вопросы по тегам