OWIN和Azure AD HTTPS到HTTP重定向循环

时间:2015-07-23 13:18:06

标签: azure redirect owin

我是OWIN的新手:)。我试图让一个页面有一个开放的公共区域,允许匿名通过HTTP,然后是一个需要身份验证的受限制的部分。我不想强制整个网站成为普通用户的HTTPS。

我遇到的问题是我收到以下循环:

  1. http://example.com/authenticatedPage - > 302重定向到AD登录
  2. 登录到AD页面HTTP 200.触发打开Azure AD链接到站点。
  3. 网站链接标识这是一个OWIN重定向并执行302重定向到http://example.com/authenticatedPage
  4. 转到1.
  5. 我已尝试过三种拦截OWIN重定向的方法,但似乎没有任何效果。

    如果我通过浏览到https://example.com/开始会话,然后单击指向authenticatedPage的链接,则登录按预期工作。即。

    1. 加载https://example.com/authenticatedPage - > 302重定向到AD
    2. 登录AD - >加载https://example.com/
    3. 302重定向到https://example.com/authenticatedPage
    4. 有没有解决这个问题而不将整个网站标记为需要SSL?

4 个答案:

答案 0 :(得分:9)

问题是您的应用程序中的OIDC中间件设置的引荐来源。会发生什么:

  1. http://foo.bar上输入您的申请并重定向到身份提供商
  2. IDP / AD根据配置的返回URI重定向到https://foo.bar
  3. Cookie由具有安全标志的OIDC中间件设置,因此仅适用于HTTPS
  4. 中间件重定向到HTTP
  5. 的引荐来源网址
  6. Cookie未在HTTP上设置,因此返回步骤1.
  7. 这有多种解决方案,例如仅强制执行SSL,重载Authorize属性并将CookieSecure标志设置为CookieSecureOption.Never(不要这样做)。

    我更喜欢的选项是将Referrer固定在中间件本身中:

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        Authority = ...
        ClientId = ...
        RedirectUri = "https://foo.bar"
        ResponseType = "id_token",
        Scope = "openid profile",      
        SignInAsAuthenticationType = "Cookies",
    
        // Deal with the returning tokens
        Notifications = new OpenIdConnectAuthenticationNotifications
        {
            AuthorizationCodeReceived = async n =>
            {
                // Enforce the reference/redirect to be HTTPS
                var builder = new UriBuilder(n.AuthenticationTicket.Properties.RedirectUri);
                builder.Scheme = "https";
                builder.Port = 443;
                n.AuthenticationTicket.Properties.RedirectUri = builder.ToString();
            }
        }
    });
    

    这样做是将Referrer URL上的HTTP重写为HTTPS。这样,如果用户在HTTP上输入应用程序,他将在使用后自动重定向到HTTPS版本。

答案 1 :(得分:1)

您是否有特定原因要求将整个网站标记为需要SSL?可能存在上述方法,但它们可能存在风险。如果您希望在某个时刻为您的域提供会话cookie,您需要确保在没有适当安全通道的情况下永远不会发送它...并且处理两者之间的切换很棘手。如果你可以分享你不愿意为整个应用程序使用SSL的原因,这对我们来说非常有用......我们目前的假设是它是可行的,到目前为止它似乎已经成功,但可能是我们忽视的东西。

答案 2 :(得分:1)

假设我没有引入一个巨大的安全漏洞,这实际上是有效的。覆盖authorize属性并将其应用于您的控制器。如果您尝试从不安全的页面进行授权,它将在尝试身份验证之前首先将您重定向到页面的HTTPS://。这意味着Azure的重定向将重定向回HTTPS,它就像魅力一样。 Cookie保持安全,每个人都是赢家!

using System.Web.Mvc;

namespace Spenceee.Attributes
{
    public class AuthorizeFromHTTPAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (!filterContext.HttpContext.Request.IsSecureConnection)
            {
                UriBuilder redirectUrl = new UriBuilder(
                   filterContext.HttpContext.Request.Url);
                redirectUrl.Scheme = "HTTPS";
                redirectUrl.Port = 443;
                filterContext.HttpContext.Response.Redirect(redirectUrl.ToString());
                return;
            }
            else
            {
                base.OnAuthorization(filterContext);
            }
        }
    }
} 

答案 3 :(得分:0)

正如维托里奥所说,强迫整个网站使用SSL可以解决问题。假设这是一个可行的方案,只需在Application_Start的{​​{1}}方法中添加全局过滤器:

Global.asax.cs

用户现在可以使用HTTP或HTTPS访问您的应用,并且在身份验证后将正确地重新路由,而无需使用无限重定向循环。