OWIN 和 Azure AD HTTPS 到 HTTP 重定向循环
OWIN and Azure AD HTTPS to HTTP Redirect Loop
我对 OWIN 还很陌生 :)。我正在尝试创建一个带有开放 public 区域的页面,该区域将允许通过 HTTP 匿名,然后是一个需要身份验证的受限部分。对于一般用户,我不想强制整个网站使用 HTTPS。
我遇到的问题是我收到以下循环:
- http://example.com/authenticatedPage -> 302 重定向到 AD 登录
- 登录到 AD 页面 HTTP 200。触发 Azure AD link 到站点的打开。
- Link 到站点标识这是一个 OWIN 重定向并执行 302 重定向到 http://example.com/authenticatedPage
- 转到 1。
我已经尝试了 3 种方法来拦截 OWIN 中的重定向,但似乎没有任何效果。
如果我通过浏览到 https://example.com/ 开始会话,然后单击 link 到 authenticatedPage,那么登录将按我预期的方式工作。即
- 加载https://example.com/authenticatedPage -> 302重定向到AD
- 登录到 AD -> 加载 https://example.com/
- 302 重定向到 https://example.com/authenticatedPage
有没有办法在不将我的整个网站标记为需要 SSL 的情况下解决这个问题?
您是否出于特定原因不想将整个站点标记为需要 SSL?可能有解决上述问题的方法,但它们可能有风险。如果您希望在某个时候为您的域设置一个会话 cookie,您希望确保它不会在没有适当的安全通道的情况下被发送……并且处理两者之间的切换是很棘手的。如果您可以分享您不愿意在整个应用程序中使用 SSL 的原因,那对我们来说将非常有用……我们目前的假设是它是可行的,到目前为止它似乎成功了,但可能成为我们忽视的东西。
假设我没有引入巨大的安全漏洞,这确实有效。覆盖授权属性并将其应用于您的控制器。如果您尝试从不安全的页面进行授权,它会先将您重定向到该页面的 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);
}
}
}
}
问题是由您的应用程序中的 OIDC 中间件设置的引荐来源网址。这是怎么回事:
- 在 http://foo.bar 上输入您的申请并重定向到身份提供商
- IDP/AD 根据配置 return URI
重定向到 https://foo.bar
- Cookie 由带有安全标志的 OIDC 中间件设置,因此仅适用于 HTTPS
- 中间件重定向到引荐来源 URL,这是 HTTP
- HTTP 上未设置 Cookie,因此返回步骤 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();
}
}
});
这样做是将 Referrer URL 上的 HTTP 重写为 HTTPS。这样,如果用户在 HTTP 上输入应用程序,他将在使用后自动重定向到 HTTPS 版本。
正如 Vittorio 所建议的,强制整个站点使用 SSL 可以解决这个问题。假设这对您来说是可行的方案,只需在 Global.asax.cs
:
的 Application_Start
方法中添加一个全局过滤器
protected void Application_Start()
{
GlobalFilters.Filters.Add(new RequireHttpsAttribute());
...
用户现在可以使用 HTTP 或 HTTPS 访问您的应用程序,并且在身份验证后将被正确地重新路由,而无需无限重定向循环。
我对 OWIN 还很陌生 :)。我正在尝试创建一个带有开放 public 区域的页面,该区域将允许通过 HTTP 匿名,然后是一个需要身份验证的受限部分。对于一般用户,我不想强制整个网站使用 HTTPS。
我遇到的问题是我收到以下循环:
- http://example.com/authenticatedPage -> 302 重定向到 AD 登录
- 登录到 AD 页面 HTTP 200。触发 Azure AD link 到站点的打开。
- Link 到站点标识这是一个 OWIN 重定向并执行 302 重定向到 http://example.com/authenticatedPage
- 转到 1。
我已经尝试了 3 种方法来拦截 OWIN 中的重定向,但似乎没有任何效果。
如果我通过浏览到 https://example.com/ 开始会话,然后单击 link 到 authenticatedPage,那么登录将按我预期的方式工作。即
- 加载https://example.com/authenticatedPage -> 302重定向到AD
- 登录到 AD -> 加载 https://example.com/
- 302 重定向到 https://example.com/authenticatedPage
有没有办法在不将我的整个网站标记为需要 SSL 的情况下解决这个问题?
您是否出于特定原因不想将整个站点标记为需要 SSL?可能有解决上述问题的方法,但它们可能有风险。如果您希望在某个时候为您的域设置一个会话 cookie,您希望确保它不会在没有适当的安全通道的情况下被发送……并且处理两者之间的切换是很棘手的。如果您可以分享您不愿意在整个应用程序中使用 SSL 的原因,那对我们来说将非常有用……我们目前的假设是它是可行的,到目前为止它似乎成功了,但可能成为我们忽视的东西。
假设我没有引入巨大的安全漏洞,这确实有效。覆盖授权属性并将其应用于您的控制器。如果您尝试从不安全的页面进行授权,它会先将您重定向到该页面的 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);
}
}
}
}
问题是由您的应用程序中的 OIDC 中间件设置的引荐来源网址。这是怎么回事:
- 在 http://foo.bar 上输入您的申请并重定向到身份提供商
- IDP/AD 根据配置 return URI 重定向到 https://foo.bar
- Cookie 由带有安全标志的 OIDC 中间件设置,因此仅适用于 HTTPS
- 中间件重定向到引荐来源 URL,这是 HTTP
- HTTP 上未设置 Cookie,因此返回步骤 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();
}
}
});
这样做是将 Referrer URL 上的 HTTP 重写为 HTTPS。这样,如果用户在 HTTP 上输入应用程序,他将在使用后自动重定向到 HTTPS 版本。
正如 Vittorio 所建议的,强制整个站点使用 SSL 可以解决这个问题。假设这对您来说是可行的方案,只需在 Global.asax.cs
:
Application_Start
方法中添加一个全局过滤器
protected void Application_Start()
{
GlobalFilters.Filters.Add(new RequireHttpsAttribute());
...
用户现在可以使用 HTTP 或 HTTPS 访问您的应用程序,并且在身份验证后将被正确地重新路由,而无需无限重定向循环。