为了显示:
>原始协议是https
>人们会认为这应该是登录之类的“默认”,但如图所示,重定向(似乎)不会维护它.
我试过的东西:
>可以使用RequireHttps属性,但是:
>似乎“奇怪”,需要2次重定向才能获得“那里”
>在你有负载均衡器和/或在其他地方(不在服务器中)“卸载”SSL的情况下,那么这将是一个重定向循环(SSL在客户端和前端net / ssl lb之间,http到你的盒(ES)/应用程序).这实际上是我的生产案例……
>我已经设置了IIS URL重写(也称为整个站点的https规范规则),并且似乎“忽略”(也)(规则不检查“https”,否则它会遭受相同的重定向循环).
>尝试并且无法在LoginPath中设置绝对URL(在CookieAuthenticationOptions中).. because you can’t do that …
感谢您的建议或指点……
更新
至于“为什么”?
- in situations where you have a load balancer and/or have SSL “offloaded” elsewhere (not in server),then this would then be a
redirect loop (SSL is between client and front-end net/ssl lb,andhttp
to your Box(es)/application). This is actually my production
case..
进一步的修补使我进入上面,如此(localhost – 我的本地开发框,而不是服务器)请求序列(上述问题在生产负载平衡环境中显示,其中SSL处理是“堆栈” – 例如ARR):
>事实上协议得到维护
>问题似乎与应用程序和“基础架构”不“匹配”的情况完全相关.看起来类似于在代码中你会在“负载平衡”/“网络服务器场”环境中执行Request.IsSecureConnection
的情况(比如ARR,其中证书在您的ARR中,而不在您的主机中).在这种情况下,该检查将始终返回false.
那么问题是关于如何解决这个问题的指导?
更新2
非常感谢理查德在试图解决这个问题时改变了我的“方向”.我原本想找到一种方法:
> set / tell OWIN / Identity使用安全URL(显式)并“覆盖”它评估LoginPath的方式.处理cookie的安全(唯一)选项以某种方式引导我(如果我只能在HTTPS中明确说出cookie,那么它给我的印象是能够为LoginPath.one方式或其他方式这样做)
>在我看来,一种“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>
并在隧道尽头看到一些亮光.
更新3
非常感谢理查德的侦探!最新的答案让我也得到了调查,结果发现有一个与CookieApplyRedirectContext相关的few posts here on SO …所以现在这就是我所拥有的(这是我的具体情况),并且是我最初的追求:
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); } } });
解决方法
负载均衡器
配置负载均衡器以重写从http到https的重定向响应.如果您使用的是ARR,则以下规则(取自here)应该有效:
<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>
其他负载平衡器将需要类似的配置.
应用
我们可以使用相对URL替换OWIN在授权过程中重定向到的URL,这意味着协议将保留为以前使用的浏览器.
在Owin源代码中花了一些时间来寻找如何做到这一点,但是对应用程序启动的以下更改应该可以解决您的问题.首先,从启动配置中提取CookieAuthenticationProvider初始化.
更改:
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,Provider = new CookieAuthenticationProvider { // Move these options in the step below... } });
至:
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,Provider = cookieProvider });
虽然我们无法轻易找到重定向规则的设置位置,但OWIN使用委托来执行实际的重定向.我在这里做的是存储该委托,修改它将要给出的URL,然后再次调用它.