【问题标题】:Why is User.Identity.IsAuthenticated == false when called via CORS为什么通过 CORS 调用时 User.Identity.IsAuthenticated == false
【发布时间】:2020-03-18 08:42:43
【问题描述】:

为什么通过 CORS 调用时 User.Identity.IsAuthenticated == false,但通过同一个域调用时为 true?

我有一个启用了 CORS 的可工作的 asp.net core 2 cookieauth 应用程序。

当我打电话时;

api/身份/建立会话

一个 AUTHCOOKIE 被丢弃在两者中
CORS 和本地 ajax 调用。
相反,当我打电话时

api/身份/注销

AUTHCOOKIE 被删除。到目前为止一切顺利。

成功建立会话后,当我调用以下命令时;

api/Identity/check-authentication

通过 CORS 调用时,User.Identity.IsAuthenticated == false,但从同一域调用时,User.Identity.IsAuthenticated == true。
我不知道这是因为我在 javascript 中如何调用它,还是我在 asp.net 应用程序上配置了错误。我以为我只需要在我的 fetch 调用中设置凭据:'include'?

[Produces("application/json")]
[Route("api/Identity")]
public class IdentityController : Controller
{
    [HttpPost]
    [AllowAnonymous]
    [Route("establish-session")]
    public async Task EstablishAuthenticatedSession(string username, string password)
    {

        var properties = new AuthenticationProperties
        {
            IsPersistent = true,
            ExpiresUtc = DateTime.UtcNow.AddHours(1)
        };

        var claims = new[] {new Claim("name", username), new Claim(ClaimTypes.Role, "User")};
        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        await
            HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(identity),
                properties);
    }

    [HttpGet]
    [AllowAnonymous]
    [Route("sign-out")]
    public async Task Logout()
    {
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    }
    [HttpGet]
    [AllowAnonymous]
    [Route("check-authentication")]
    public async Task<bool> CheckAuthentication()
    {
        return User.Identity.IsAuthenticated;
    }
}

这是我的 javascript sn-ps;

establishAuthenticatedSession(){

            let self = this;
            var model = this.get();
            console.log(model);
            var url = "https://localhost:44310/api/Identity/establish-session?username=herb&password=1234";
            fetch(url,
            {
                credentials: 'include',
                headers: { 'Content-Type': 'text/plain' },
                method: 'POST'
            })
            .then(function (res) {
                console.log(res);
                self.set({ establishSession:{ message:"Success" }});
            }).catch(function(error) {
                self.set({ establishSession:{ message:error.message }});
                console.log('There has been a problem with your fetch operation: ' + error.message);
            });

        },
        signOut(){

            let self = this;
            var model = this.get();
            console.log(model);
            var url = "https://localhost:44310/api/Identity/sign-out";
            fetch(url,
            {
                credentials: 'include',
                headers: { 'Content-Type': 'text/plain' },
                method: 'GET'
            })
            .then(function (res) {
                console.log(res);
                self.set({ signoutResult:{ message:"Success" }});
            }).catch(function(error) {
                self.set({ signoutResult:{ message:error.message }});
                console.log('There has been a problem with your fetch operation: ' + error.message);
            });

        },
        checkAuthenticatedSession(){
            let self = this;
            var model = this.get();
            console.log(model);
            var url = "https://localhost:44310/api/Identity/check-authentication";
            fetch(url,
            {
                credentials: 'include',
                method: 'GET',
                headers: { 'Content-Type': 'text/plain' }
            })
            .then(res => res.text())
            .then(function (res) {
                console.log(res);
                self.set({ checkAuthenticatedSession:{ message:res }});
            })
            .catch(function(error) {
                self.set({ checkAuthenticatedSession:{ message:error.message }});
                console.log('There has been a problem with your fetch operation: ' + error.message);
            });
        }

这是我的 CORS 设置;

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

【问题讨论】:

  • 所以我想我知道为什么,即使凭据:包含,我的 AUTHCOOKIE 也没有被发送。我也可以使用test-cors.org 重现这一点。所以看起来这就是cookie的制作方式可能是原因。浏览器发回 CORS 创建的 cookie 需要什么特别的东西吗?

标签: cookies cross-domain asp.net-core-2.0 fetch-api


【解决方案1】:

所以事实证明cookie需要设置为SameSiteMode.None。我得到的提示是,ARRAfinity cookie 从 azure 设置为 non,并且它被发送到我不在的地方。

在我的应用程序中,我必须将其设置如下;

public class Startup
{
    ...

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        ...           

        services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                // sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie(
                CookieAuthenticationDefaults.AuthenticationScheme,
                options =>
                {
                    options.LoginPath = "/Account/LogIn"; ;
                    options.AccessDeniedPath = new PathString("/account/login");
                    options.Cookie.Name = "AUTHCOOKIE";
                    options.ExpireTimeSpan = new TimeSpan(365, 0, 0, 0);
                    options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
                    options.Cookie.SameSite = SameSiteMode.None;

                }
            );
        ...
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        ...
        var cookiePolicyOptions = new CookiePolicyOptions
        {
            Secure = CookieSecurePolicy.SameAsRequest,
            MinimumSameSitePolicy = SameSiteMode.None
        };

        app.UseCookiePolicy(cookiePolicyOptions);
        ...
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2019-06-30
    • 2018-03-14
    • 2021-05-12
    • 2013-07-12
    相关资源
    最近更新 更多