创建可由 NET Core 使用的自定义 cookie API

Create a custom cookie that can be consumed by a NET Core API

我有一个用于后端的 .NET Core 3.1 API 和一个 Angular 前端。两者之间的身份验证很好,使用 JWT 令牌完成。 现在,因为我需要与另一个应用程序集成,所以我使用此 instruction blog 将 cookie 身份验证添加到 API。 Startup.cs 中的类似内容:

services.AddAuthentication()
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, opt =>
    {
        opt.Cookie.Name = ".SharedCookie";
        opt.Cookie.Path = "/";
        opt.Cookie.Domain = ".localhost";
        opt.SlidingExpiration = true;
        opt.ExpireTimeSpan = new TimeSpan(24 * 7, 0, 0);
    })

到目前为止一切顺利。 API 有一个用于注册、登录和注销的端点。但是,我希望我的 API 仅使用 cookie 进行授权。 cookie 将由另一个应用程序创建,而不是 API 或我的前端应用程序。

这意味着我有另一个应用程序(在不同的技术堆栈中,例如 Python,NodeJS)将负责身份验证。当用户成功登录时,将创建一个 cookie 并将其存储在浏览器中。然后,当用户访问我的 Angular 应用程序并从那里向我的 .NET Core API 发出请求(附加 cookie)时,我的 API 可以基于该 cookie 进行身份验证和授权.

我环顾四周,不确定在 NET Core 方面该做什么。
例如,从 this tutorial,我看到一个应用程序可以创建这样的 cookie

res.cookie(
    'token',
    jwt.sign(
        { username: row.username, email: row.email },
        config.secret
    ),
    {
        domain: `.my-domain.com`
    }
);

我的 NET Core API 如何使用它?我这么问是因为 NET API 创建的 cookie 格式似乎不同。我可以更改 NET API 或更改由第 3 方应用程序创建的 cookie 格式。

非常感谢。

因为要求完全不符合任何标准。我们最好的机会可能是构建我们自己的身份验证方案。像

public class CustomCookieAuthenticationOptions : AuthenticationSchemeOptions
{
}

public class CustomCookieAuthenticationHandler : AuthenticationHandler<CustomCookieAuthenticationOptions>
{
    public CustomCookieAuthenticationHandler(IOptionsMonitor<CustomCookieAuthenticationOptions> options, ILoggerFactory logger,
        UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        if (Request.Cookies.TryGetValue("myCookie", out var customCookie))
        {
            // Some process to extract data was needed from the cookie and build ticket like below
            var cookieClaims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, "PreviousProcessValueOne"),
                new Claim(ClaimTypes.Email, "PreviousProcessValueTwo"),
                new Claim(ClaimTypes.Name, "PreviousProcessValueThree")
            };

            var cookieClaimsIdentity = new ClaimsIdentity(cookieClaims, nameof(CustomCookieAuthenticationHandler));
            var customTicket = new AuthenticationTicket(new ClaimsPrincipal(cookieClaimsIdentity), Scheme.Name);
            return Task.FromResult(AuthenticateResult.Success(customTicket));
        }
        
        return Task.FromResult(AuthenticateResult.Fail("Cookie not presented!"));
    }
}

然后通过身份验证过程注册它

services.AddAuthentication(opts => opts.DefaultScheme = JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer()
    .AddScheme<CustomCookieAuthenticationOptions, CustomCookieAuthenticationHandler>("MyCustomCookieScheme", null);

当使用它来保护我们的端点时

[Authorize(AuthenticationSchemes = "MyCustomCookieScheme")]
public IActionResult TestAuthentication()
{
    return Ok("Authenticated!");
}