如何配置.net核心以将身份验证Cookie发送到其他域 [英] How to configure .net core to send authentication cookies to different domain

查看:98
本文介绍了如何配置.net核心以将身份验证Cookie发送到其他域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Cookie与前端使用,该前端的域与后端的域不同。后端是使用.net核心实现的,而前端是Angular。我研究了
,我需要设置withCredentials:在进行http调用时为true。但是,当我将其设置为true时,会出现此错误:

I am trying to use cookies with frontend which domain is different than backend's domain. Backend is implemented with .net core and frontend is Angular. I have researched that I need to set withCredentials: true when making http calls. But when I set it to true I get this error:


对预检请求的响应未通过访问控制检查:当请求的凭据模式为 include时,响应中的 Access-Control-Allow-Origin标头不得为通配符 *。
我一直在尝试设置CORS和Cookie设置以适应这种情况。这是我来自StartUp.cs的相关代码。
Cors设置:

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;
            });

这是我在登录控制器中登录HttpContext的方式:

Here is how I login to HttpContext in login controller:

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);

这是我的音频文件端点:

And here is my endpoint for audio files:

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

因此,如您所见,我还将JWT令牌用于身份验证。我需要Cookie,因为我使用音频元素从REST API下载了mp3文件,并且将音频元素src直接设置为我的REST API地址。因此,在使用音频元素时,我无法将JWT设置为标头。在这种情况下,当我的前端与后端位于同一个域时,Cookie可以很好地工作,但是现在我正尝试将前端也移至其他服务器和域。

So as you see I also use JWT token with authentication. I need cookies because I download mp3 file from my REST API using audio element and I'm setting audio elements src directly to my REST API address. So I can't set JWT to header when using audio element. Cookies was working well in this situation when my frontend was at same domain as backend but now I'm trying to move frontend to other server and domain as well.

怎么办我需要配置后端以从其他域中获取Cookie吗?

How do I need to configure backend to get cookies from different domain?

我的后端在Azure上。还有一些CORS设置,我可以删除*并将其替换为特殊地址。

My backend is on Azure. There is also some CORS settings where I remove * and replaced it with spesific address. Does this have something to do with this?

编辑:

找到Azure CORS设置后,异常已更改对此:

After I found Azure CORS settings, Exception changed to this:



对预检请求的响应未通过访问控制检查: Access的值响应中的-Control-Allow-Credentials标题为,当请求的凭据模式为 include时必须为 true

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核心cors设置以进行cors控制。

You need to remove all CORS settings from Azure to get your .net core cors settings to get cors control. Still no success but maybe little closer the solution.

推荐答案

最后我成功了。正如我在编辑评论中所说的,主要原因是azures CORS设置。删除它们后,我得到了.net核心设置。这是我的最终解决方案:
Cookie设置:

Finally I got it working. As I say in my edit comment, main reason was azures CORS settings. After I remove them I get my .net core settings to hit in. Here is my final solution: Cookie settings:

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");

这里是后端登录的相关代码:

Here is related code from login in backend:

await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

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

这在我的音频控制器端点中就足够了

And this was enough in my audio controller endpoint

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

在前端,我设置withCredentials:进行登录呼叫时为true。

And in frontend I set withCredentials: true when I make login call.

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

I now this is quite unsecure when I have AllowAnyOrigin instead of WithOrigin, but for some reason I didn't get it working with WithOrigin.

对于那些正在阅读此书并在天蓝色使用.net Core并想使用CORS的用户,请从Azure删除您的CORS设置,并在.net Core中处理它们,因为在.net Core中,配置要比在CORS中更多天青。这是我从互联网上找到的一些东西:

For those who are reading this and are using .net Core in azure and want use CORS remove your CORS settings from Azure and handle them in .net core because in .net core there is much more configurations than in CORS in azure. Here is some what I found from internet:

这篇关于如何配置.net核心以将身份验证Cookie发送到其他域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆