angular - 如何配置.net core以将身份验证cookie发送到不同的域

标签 angular azure cookies cors .net-core

我正在尝试在前端使用cookie,其域与后端的域不同。后端是用.net core实现的,前端是Angular。 我研究过,在进行 http 调用时需要设置 withCredentials: true 。但是当我将其设置为 true 时,我收到此错误:

Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. I have been trying to set CORS and Cookie settings to work with this situation. Here is my relevant code from StartUp.cs. Cors settings:

services.AddCors(options =>
        {
            options.AddPolicy("AllowDomainOrigin",
                builder =>
                {
                    builder
                        .WithOrigins("http://some.domain.net")
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
            options.AddPolicy("AllowForLocalhost",
                builder =>
                {
                    builder
                        .WithOrigins("http://localhost:4200")
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                });
        });
services.AddSession(options =>
        {
            options.Cookie.SameSite = SameSiteMode.None;
        });
...
        app.UseCors("AllowDomainOrigin");
        app.UseCors("AllowForLocalhost");

Cookie 设置:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => 
            {
                options.Cookie.Domain = "some.domain.net";
                options.Cookie.Name = "access_token";
                options.Cookie.SameSite = SameSiteMode.None;
                options.LoginPath = "/login";
                options.LogoutPath = "/login";
            })
            .AddCookie("localhost", options => 
            {
                options.Cookie.Domain = "localhost";
                options.Cookie.Name = "localhost_access_token";
                options.Cookie.SameSite = SameSiteMode.None;
                options.LoginPath = "/login";
                options.LogoutPath = "/login";
            })
            .AddCookie("othercloud", options => 
            {
                options.Cookie.Domain = "domain.com";
                options.Cookie.Name = "musiple_access_token";
                options.Cookie.SameSite = SameSiteMode.None;
                options.LoginPath = "/login";
                options.LogoutPath = "/login";
            })
            .AddJwtBearer(options => 
            {
                options.TokenValidationParameters = tokenValidationParameters;
            });

以下是我在登录 Controller 中登录 HttpContext 的方法:

await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync("localhost");
await HttpContext.SignOutAsync("othercloud");
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
            new ClaimsPrincipal(identity),
            authProperties);
await HttpContext.SignInAsync("localhost",
            new ClaimsPrincipal(identity),
            authProperties);
await HttpContext.SignInAsync("othercloud",
            new ClaimsPrincipal(identity),
            authProperties);

这是我的音频文件端点:

[HttpGet("{id}")]
[Authorize(AuthenticationSchemes= CookieAuthenticationDefaults.AuthenticationScheme +", localhost, othercloud")]
public async Task<FileStreamResult> Get(int id)

正如您所见,我还使用 JWT token 进行身份验证。我需要 cookie,因为我使用音频元素从 REST API 下载 mp3 文件,并且我将音频元素 src 直接设置为我的 REST API 地址。因此,在使用音频元素时,我无法将 JWT 设置为 header 。当我的前端与后端位于同一域时,Cookie 在这种情况下运行良好,但现在我也尝试将前端移动到其他服务器和域。

我需要如何配置后端才能从不同域获取 cookie?

我的后端位于 Azure 上。还有一些 CORS 设置,我删除了 * 并将其替换为特定地址。这和这个有关系吗?

编辑:

找到Azure CORS设置后,异常更改为:

Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'

编辑2:

您需要从 Azure 中删除所有 CORS 设置,才能让 .net core cors 设置获得 cors 控制。仍然没有成功,但可能更接近解决方案。

最佳答案

终于我成功了。正如我在编辑评论中所说,主要原因是 azures CORS 设置。删除它们后,我就可以使用 .net core 设置了。这是我的最终解决方案: Cookie 设置:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => 
            {
                options.Cookie.Name = "access_token";
                options.Cookie.SameSite = SameSiteMode.None;
            })
            .AddJwtBearer(options => 
            {
                options.TokenValidationParameters = tokenValidationParameters;
            });

CORS 设置:

services.AddCors(options =>
        {
            options.AddPolicy("AllowAllOrigins",
                builder =>
                {
                    builder
                        .AllowAnyOrigin()
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                });
        });
...

app.UseCors("AllowAllOrigins");

以下是后台登录的相关代码:

await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
            new ClaimsPrincipal(identity),
            authProperties);

这对于我的音频 Controller 端点来说已经足够了

[HttpGet("{id}")]
[Authorize()]
public async Task<FileStreamResult> Get(int id)

在前端,当我进行登录调用时,我设置了 withCredentials: true 。

现在,当我使用AllowAnyOrigin而不是WithOrigin时,这是非常不安全的,但由于某种原因,我没有让它与WithOrigin一起使用。

对于那些正在阅读本文并在 azure 中使用 .net Core 并希望使用 CORS 的人,请从 Azure 中删除 CORS 设置并在 .net core 中处理它们,因为在 .net core 中的配置比 azure 中的 CORS 要多得多。以下是我从网上找到的一些内容:

关于angular - 如何配置.net core以将身份验证cookie发送到不同的域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49218862/

相关文章:

angular - 在可观察的 Angular http 中传递 header

具有 VMSS 的 Azure 应用程序网关

ios - 如何在 Swift 中的 WkWebView 中设置 Cookie?

typescript - 将 CodeMirror 与 Angular2 集成( typescript )

json - Angular : ERROR SyntaxError: Unexpected token < in JSON at position 0

azure - 为什么我的 webjob 终止而不抛出异常?

禁用 cookie 的 PHP session ,它有效吗?

session - express.cookieSession 破坏 session.destroy

Angular 输入 setter 仅触发一次

Azure 和 AzureRM Powershell 模块冲突