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

Spe*_*nce 4 redirect azure 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.

我尝试了三种拦截OWIN重定向的方法,但似乎没有任何效果.

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

  1. 加载https://example.com/authenticatedPage - > 302重定向到AD
  2. 登录AD - >加载https://example.com/
  3. 302重定向到https://example.com/authenticatedPage

无论如何要解决这个问题而不将整个网站标记为需要SSL吗?

ran*_*uwe 10

问题是您的应用程序中的OIDC中间件设置的引荐来源.这是怎么回事:

  1. http://foo.bar上输入您的应用程序并重定向到Identity provider
  2. IDP/AD 根据配置的返回URI 重定向到https://foo.bar
  3. Cookie由OIDC中间件设置,具有安全标志,因此仅适用于HTTPS
  4. 中间件重定向到引用URL,即HTTP
  5. Cookie未在HTTP上设置,因此返回步骤1.

有多种解决方案,例如仅强制执行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();
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

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


Spe*_*nce 1

假设我没有引入一个巨大的安全漏洞,这实际上是有效的。覆盖授权属性并将其应用到您的控制器。如果您尝试从不安全的页面进行授权,它会先将您重定向到该页面的 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);
            }
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)