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

Posted

技术标签:

【中文标题】创建可由 NET Core API 使用的自定义 cookie【英文标题】:Create a custom cookie that can be consumed by a NET Core API 【发布时间】:2022-01-11 22:21:13 【问题描述】:

我有一个用于后端的 .NET Core 3.1 API 和一个 Angular 前端。两者之间的身份验证很好,使用 JWT 令牌完成。 现在,因为我需要与另一个应用程序集成,我正在使用这个instruction blog 向 API 添加 cookie 身份验证。 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,我看到一个app可以创建这样的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 或更改由 3rd-party 应用程序创建的 cookie 格式。

非常感谢。

【问题讨论】:

【参考方案1】:

由于要求完全超出任何标准。我们最好的机会可能是构建我们自己的身份验证方案。类似的东西

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

【讨论】:

非常感谢!我对您的代码进行了一些小改动,现在它可以工作了!顺便问一下,您的代码块中的SystemAuthenticationRelatedHandler 是什么? 那里的 3 行代码我只是从一个实践项目中获取的,在这种情况下应该是 CustomCookieAuthenticationHandler。我更新了答案以解决该问题。很高兴它帮助顺便说一句

以上是关于创建可由 NET Core API 使用的自定义 cookie的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 ASP.NET Core 中的 api 控制器更新 IdentityUser 的自定义属性?

.Net Core 3.1 Web Api 的自定义 OData 日期时间序列化程序

.NET Core 中的自定义授权属性 [重复]

如何创建不依赖于 ASP.NET Core 声明的自定义 Authorize 属性?

.NET Core 3.1 覆盖 docker compose 中的自定义值

Web api dotnet core 中的 Api 版本控制错误的自定义错误响应