OWIN和Azure AD HTTPS到HTTP的重定向循环
OWIN和Azure AD HTTPS到HTTP的重定向循环
我对OWIN非常陌生 :). 我尝试创建一个包含公开区域和需要身份验证的限制区域的页面。我不想强制整个网站都使用HTTPS来满足普通用户的需求。
问题是我遇到了以下循环:
- http://example.com/authenticatedPage -> 302 重定向到AD登录页
- AD登录页返回HTTP 200。触发Azure AD链接到网站。
- 网站链接识别到这是OWIN重定向,然后进行302重定向到http://example.com/authenticatedPage
- 返回到第1步。
我尝试了3种拦截OWIN重定向的方法,但似乎都没有起作用。
如果我通过浏览https://example.com/,然后点击链接到authenticatedPage,那么登录将按照我的预期工作。即:
- 加载https://example.com/authenticatedPage -> 302重定向到AD登录页
- AD登录 -> 加载https://example.com/
- 302重定向到https://example.com/authenticatedPage
有没有办法在不将整个网站标记为需要SSL的情况下解决这个问题?
问题出现的原因是OIDC中间件在应用程序中设置的引用者。发生的情况如下:
1. 进入应用程序,在http://foo.bar上重定向到身份提供者
2. 身份提供者/AD重定向到https://foo.bar作为配置的返回URI
3. OIDC中间件设置了带有Secure标志的Cookie,仅支持HTTPS
4. 中间件重定向到HTTP的引用者URL
5. 在HTTP上没有设置Cookie,所以回到步骤1
解决方法有多种,例如强制只使用SSL,重载授权属性,并将CookieSecure
标志设置为CookieSecureOption.Never
(不要这样做)。
我更喜欢的选择是在中间件本身中修复引用者,像这样:
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(); } } });
这样做的作用是将引用者URL上的HTTP重写为HTTPS。这样,如果用户在HTTP上进入应用程序,使用后将自动重定向到HTTPS版本。
因此,您已经在重定向之前更新了OWIN/您的中间件来执行此操作。这是一个合理的解决方案,使用开源软件。我尝试避免在开源中维护分支,但仍然是一个合理的解决方案。
这不需要对任何开源软件或分支进行任何更改。通知和AuthorizationCodeReceived处理程序已经由Microsoft在其标准中间件中实现。
在我的问题中并不明显,但我正在登录到Azure Active Directory,而不是使用OpenID身份验证。从我所了解的情况来看,该代码不像OpenID那样可扩展。此问题也已经接近一年了,所以所有的框架都已经向前发展。此外,重定向来自Azure,而不是我的代码。
AAD支持OIDC。实际上,这是他们推荐的身份验证方式。确实,它不像AAD那样可扩展,因为AAD目前不允许自定义作用域(除非您是AAD管理员并为您的应用程序设置权限)。框架确实在前进,但中间件的消耗基本相同。关于重定向,是的,它们确实来自Azure到您的主机,但您的主机然后设置Cookie并再次重定向到指定的引用者。重定向到自身是您原始问题所在的地方。
问题原因:在OWIN和Azure AD中,当从一个非安全页面尝试进行认证时,会发生HTTPS到HTTP的重定向循环。
解决方法:通过重写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); } } } }
以上代码将通过重定向将非安全连接转换为HTTPS连接,从而解决了OWIN和Azure AD之间的HTTPS到HTTP重定向循环的问题。