使用 OpenIdConnect 和 Azure AD 验证 CORS 请求
Authenticate CORS request using OpenIdConnect and Azure AD
我在 Azure 中有 Asp.Net 核心后端 运行。
HTML/JS 本地主机上的前端 运行,使用 CORS 与后端通信
当前端和后端都在本地主机上,或者它们都在 Azure 中时,身份验证有效 -> Azure AD 应用程序设置正确。
这是我的登录方式:
[Route("/api/[controller]")]
public class AccountController : Controller
{
[HttpGet]
public IActionResult Index()
{
return Json(new AccountInfoViewModel
{
IsAuthenticated = User.Identity.IsAuthenticated,
UserName = User.Identity.Name,
Roles = new string[0],
LoginUrl = Url.Action(nameof(Login), null, null, null, Request.Host.Value),
LogoutUrl = Url.Action(nameof(Login), null, null, null, Request.Host.Value),
});
}
[HttpGet("login")]
public async Task Login(string returnUrl)
{
await HttpContext.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = returnUrl });
}
[HttpGet("logoff")]
public async Task LogOff()
{
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
[HttpGet("endsession")]
public async Task EndSession()
{
// If AAD sends a single sign-out message to the app, end the user's session, but don't redirect to AAD for sign out.
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
所以从本地主机,然后我重定向到:
https://myapp.azurewebsites.net/Account/Login?returnUrl=localhost:12345
这会触发 Login
操作,并将我重定向到我的 Azure AD SSO 页面,并在登录后将我重定向回本地主机。但是请求到后台还是没有认证。
重要:
当我从登录操作中删除 redirectUrl 时,我被重定向到后端根而不是原始来源(本地主机)。来自该来源(后端)的任何请求都经过身份验证。
我不得不明确地告诉 javascript 包括身份验证 headers:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
更多详情:https://docs.microsoft.com/en-us/aspnet/core/security/cors#credentials-in-cross-origin-requests
编辑:对于 chrome 和实现 cookie 的 SameSite 属性的 opera,您还必须像这样设置身份验证 cookie:
services.AddAuthentication(...)
.AddCookie(option => option.Cookie.SameSite = SameSiteMode.None)
.AddOpenIdConnect(...)
我在 Azure 中有 Asp.Net 核心后端 运行。 HTML/JS 本地主机上的前端 运行,使用 CORS 与后端通信
当前端和后端都在本地主机上,或者它们都在 Azure 中时,身份验证有效 -> Azure AD 应用程序设置正确。
这是我的登录方式:
[Route("/api/[controller]")]
public class AccountController : Controller
{
[HttpGet]
public IActionResult Index()
{
return Json(new AccountInfoViewModel
{
IsAuthenticated = User.Identity.IsAuthenticated,
UserName = User.Identity.Name,
Roles = new string[0],
LoginUrl = Url.Action(nameof(Login), null, null, null, Request.Host.Value),
LogoutUrl = Url.Action(nameof(Login), null, null, null, Request.Host.Value),
});
}
[HttpGet("login")]
public async Task Login(string returnUrl)
{
await HttpContext.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = returnUrl });
}
[HttpGet("logoff")]
public async Task LogOff()
{
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
[HttpGet("endsession")]
public async Task EndSession()
{
// If AAD sends a single sign-out message to the app, end the user's session, but don't redirect to AAD for sign out.
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
所以从本地主机,然后我重定向到:
https://myapp.azurewebsites.net/Account/Login?returnUrl=localhost:12345
这会触发 Login
操作,并将我重定向到我的 Azure AD SSO 页面,并在登录后将我重定向回本地主机。但是请求到后台还是没有认证。
重要: 当我从登录操作中删除 redirectUrl 时,我被重定向到后端根而不是原始来源(本地主机)。来自该来源(后端)的任何请求都经过身份验证。
我不得不明确地告诉 javascript 包括身份验证 headers:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
更多详情:https://docs.microsoft.com/en-us/aspnet/core/security/cors#credentials-in-cross-origin-requests
编辑:对于 chrome 和实现 cookie 的 SameSite 属性的 opera,您还必须像这样设置身份验证 cookie:
services.AddAuthentication(...)
.AddCookie(option => option.Cookie.SameSite = SameSiteMode.None)
.AddOpenIdConnect(...)