ASP.Net身份登录重定向强制协议(Https)

EdS*_*dSF 19 asp.net-mvc owin asp.net-identity-2

希望我只是遗漏了一些非常简单/明显的东西 - 为什么,更重要的是,如何在重定向期间维护(或强制)协议Login

为了显示:

请求跟踪

  • 原始协议是 https
  • 人们会认为这应该是类似的"默认" login,但如图所示,重定向(似乎)不能保持它.

我试过的东西:

  • RequireHttps一个可以使用的属性,但是:

    1. 似乎"奇怪",需要2次重定向才能获得"那里"
    2. 在你有负载均衡器和/或在其他地方(不在服务器中)"卸载"SSL的情况下,这将是一个重定向循环(SSL在客户端和前端net/ssl lb之间,以及http你的盒子之间( ES)/应用程序).这实际上是我的生产案例......
  • 我已经设置了IIS URL重写(也称为整个站点的https 规范规则),并且似乎"忽略"(也)(规则不检查"https",否则它会遭受相同的重定向循环).

  • 尝试并且未能在LoginPath(in CookieAuthenticationOptions)中设置绝对URL .. 因为你不能这样做 ......

感谢您的建议或指点......


更新

至于"为什么"

  1. 在你有负载均衡器和/或在其他地方(不在服务器中)"卸载"SSL的情况下,这将是一个 重定向循环(SSL在客户端和前端net/ssl lb之间,以及http你的盒子之间( ES)/应用程序).这实际上是我的生产案例..

进一步的修补使我进入上面,如此(localhost - 我的本地开发框,而不是服务器)请求序列(上述问题表现在生产负载平衡环境中,其中SSL处理是"堆栈" - 例如ARR):

localhost https

  • 事实上该协议得以维持
  • 问题似乎与应用程序和"基础架构"不"匹配" 的情况完全相关.看起来类似于在代码中你会在"负载平衡"/"网络农场"环境中进行操作的情况(比如ARR 在你的ARR中,而不在你的主机中).在这种情况下,该检查将始终返回..Request.IsSecureConnectioncertfalse

那么问题是关于如何解决这个问题的指导呢?


更新2

非常感谢理查德在试图解决这个问题时改变了我的"方向".我原本想找到一种方法:

  • set/tell OWIN/Identity使用安全URL(显式)并"覆盖"它的评估方式LoginPath.Secure处理cookie 的(唯一)选项以某种方式引导我(如果我只能在HTTPS中明确说出cookie,那么它给我的印象是能够以LoginPath某种方式或其他方式这样做)

  • 在我看来,一种"hacky"方式就是处理客户端(Javascript).

最后,理查德的回答把我带到了URL重写(虽然仍然没有在LB方面,因为这超出了我的控制范围).我目前正在处理(基于我的环境):

<rule name="Redirect to HTTPS" stopProcessing="true">
    <match url=".*" />

    <conditions>
      <add input="{HTTP_CLUSTER_HTTPS}" pattern="^on$" negate="true" />
      <add input="{HTTP_CLUSTER_HTTPS}" pattern=".+" negate="true" />

    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}{SCRIPT_NAME}/{REQUEST_URI}" redirectType="SeeOther" />
</rule>
Run Code Online (Sandbox Code Playgroud)

并在隧道尽头看到一些亮光.


更新3

非常感谢理查德的侦探!最新的答案也让我得到了调查,结果发现这里有很多关于CookieApplyRedirectContext相关的帖子 ......所以现在这就是我所拥有的(这是我的具体情况),这就是我最初的追求:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
   AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
   LoginPath = new PathString("/Account/Login"),

   //This is why. If I could explicitly set this, then I (thought) I should
   //be able to explicitly enforce https (too..as a setting)
   //for the LoginPath...
   CookieSecure = CookieSecureOption.Always,

   Provider = new CookieAuthenticationProvider 
   {
      OnValidateIdentity = .....
      ,
      OnApplyRedirect = context =>
      {
         Uri absoluteUri;
          if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out absoluteUri))
          {
             var path = PathString.FromUriComponent(absoluteUri);
             if (path == context.OwinContext.Request.PathBase + context.Options.LoginPath)
             {
                context.RedirectUri = context.RedirectUri.Replace("http:", "https:");
             }
           }
          context.Response.Redirect(context.RedirectUri);
        }
     }
});
Run Code Online (Sandbox Code Playgroud)

Ric*_*ard 13

出现此问题的原因是您的应用程序正在向绝对URL发出重定向.您可以在负载均衡器或应用程序本身中以两种方式之一解决此问题.

负载均衡器

配置负载均衡器以重写从http到https的重定向响应.如果您使用的是ARR,则以下规则(取自此处)应该有效:

<rule name="forum-redirect" preCondition="IsRedirection" enabled="true">
  <match serverVariable="RESPONSE_LOCATION" pattern="^http://[^/]+/(.*)" />
  <conditions>
    <add input="{ORIGINAL_HOST}" pattern=".+" />
  </conditions>
  <action type="Rewrite" value="http://{ORIGINAL_HOST}/{R:1}" />
</rule>
Run Code Online (Sandbox Code Playgroud)

其他负载平衡器将需要类似的配置.

应用

我们可以使用相对URL替换OWIN在授权过程中重定向到的URL,这意味着协议将保留为以前使用的浏览器.

在Owin源代码中花了一些时间来查找如何执行此操作,但是对应用程序启动的以下更改应该可以解决您的问题.首先,从启动配置中提取CookieAuthenticationProvider初始化.

更改:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider 
    {
        // Move these options in the step below...
    }
});
Run Code Online (Sandbox Code Playgroud)

至:

var cookieProvider = new CookieAuthenticationProvider
{ 
    // ... Options from your existing application
};
// Modify redirect behaviour to convert login URL to relative
var applyRedirect = cookieProvider.OnApplyRedirect;
cookieProvider.OnApplyRedirect = context =>
{
    if (context.RedirectUri.StartsWith("http://" + context.Request.Host))
    {
        context.RedirectUri = context.RedirectUri.Substring(
            context.RedirectUri.IndexOf('/', "http://".Length));
    }
    applyRedirect(context);
};

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = cookieProvider
});
Run Code Online (Sandbox Code Playgroud)

虽然我们无法轻易找到重定向规则的设置位置,但OWIN使用委托来执行实际的重定向.我在这里做的是存储该委托,修改它将要给出的URL,然后再次调用它.

使用此选项,确保您站点中的任何其他重定向和链接都是相对的.

  • 它是LB的错-如果将您的http流量封装到https中,那么它应该会识别到权威的URL到http版本的重定向,并将其替换为https链接。如果您使用的是ARR,则需要[出站重写规则](http://www.iis.net/learn/extensions/url-rewrite-module/creating-outbound-rules-for-url-rewrite-module )。我添加了一条规则可能会起作用。 (2认同)