ASP.NET Core 5 OpenIdConnect 身份验证 cookie 在理论上是如何工作的?

Posted

技术标签:

【中文标题】ASP.NET Core 5 OpenIdConnect 身份验证 cookie 在理论上是如何工作的?【英文标题】:How do the ASP.NET Core 5 OpenIdConnect authentication cookies work in theory? 【发布时间】:2022-01-14 03:18:51 【问题描述】:

我们正在尝试了解身份验证 cookie(ASP.NET Core 5.0 - Microsoft.AspNetCore.Authentication.OpenIdConnect 5.0.11 版)如何与没有 PKCE 的授权代码流一起工作。

认证过程

auth 过程如下所示:前端的登录重定向到AuthController 的登录端点,并启动 OpenId Connect 过程。因此,您已通过身份提供者的身份验证,并且为用户设置了 cookie。每次调用 API 时都会发送这些信息,以检查请求是否经过身份验证。

在此过程中创建了 3 个 cookie:

饼干#1:

名称 = .AspNetCore.Cookies 值 = chunks-2

饼干 #2:

名称 = .AspNetCore.CookiesC1 值 = CfDJ8GRK-GHfascFTvp0o_E7oKZU-6GOAbUGCPHZZPfewEv12PmKgr46gfeTQC351e-Jnxq8SxzjJEgboIedIPCO11Q […]

饼干#3:

名称 = .AspNetCore.CookiesC2 值 = 8G86qN27NOS2Z-75XqY34d-ID1nOELpPaHUIe2EkFZMmfjrYSKA2JaU30p4Ozh8RyxZXTpFCRV8

问题

这些.AspNetCore cookie 如何用于身份验证? 如何生成名称和加密值? 这些 cookie 包含什么内容?

我们试图解密 cookie (How to manually decrypt an ASP.NET Core Authentication cookie?) 以了解它的工作原理,但这对我们不起作用。

遗憾的是,理论上我们还没有找到关于 cookie 是如何生成(带有名称和值)的答案。

我希望这些问题是可以理解的,如果有人可以回答,我将不胜感激。

编码 sn-ps 以便更好地理解。希望:)

AuthController:

// https://auth0.com/blog/backend-for-frontend-pattern-with-auth0-and-dotnet/
public class AuthController : Controller

    public ActionResult Login(string returnUrl = "/login")
    
        return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties()  RedirectUri = returnUrl );
    

    [Authorize]
    public async Task<ActionResult> Logout()
    
        await HttpContext.SignOutAsync();

        return new SignOutResult(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties
        
            //RedirectUri = Url.Action("Index", "Home")
            RedirectUri = "/logout"
        );
    

    //[Authorize]
    public ActionResult GetUser()
    
        var jsonReturn = new Dictionary<string, string>();

        if (User != null && User.Identity.IsAuthenticated)
        
            jsonReturn.Add("isAuthenticated", "true");

            foreach (var claim in ((ClaimsIdentity)this.User.Identity).Claims)
            
                jsonReturn.Add(claim.Type, claim.Value);
            

            return Json(JsonConvert.SerializeObject(jsonReturn));
        

        jsonReturn.Add("isAuthenticated", "false");
        return Json(JsonConvert.SerializeObject(jsonReturn));
    

启动:

public void ConfigureServices(IServiceCollection services)

     JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

     services.AddAuthentication(options =>
     
          options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
          options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
          options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
     )
     .AddCookie(o =>
     
          o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
          o.Cookie.SameSite = SameSiteMode.Strict;
          o.Cookie.HttpOnly = true;
     )
     .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => ConfigureOpenIdConnect(options));


private void ConfigureOpenIdConnect(OpenIdConnectOptions options)

        options.Authority = <identity provider url>;
        options.ClientId = "<clientId>";
        options.ClientSecret = "<clientSecret>";

        options.ResponseMode = OpenIdConnectResponseMode.FormPost;
        options.Scope.Clear();
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("offline_access");
        
        options.CallbackPath = new PathString("/callback");
        options.SaveTokens = true;
        options.UseTokenLifetime = false;

【问题讨论】:

没有“ASP.NET 5”之类的东西。请准确地说明您使用的是什么。 另外,在这种情况下,谁是“我们”?你的团队有多大?您的团队对委托 authX 的熟悉程度如何(作为一般原则)? .AspNetCore.Cookies cookie 不是 2 个 cookie,而是被分成 2 个块的单个 cookie,否则它会超出浏览器对单个 cookie 长度的常见限制。也就是说,如果您的 authx cookie 将超过 ~1KB,您确实应该使用服务器端存储。 对不起。我的意思是 ASP.NET Core 5,在这种情况下,“我们”只是另一个人和我。自 10 月左右以来,我们一直在使用身份验证流程。在此之前,我们一般对身份验证知之甚少。也感谢您的回答,我们将尝试实现服务器端存储 【参考方案1】:

.AspNetCore cookie 由 Cookie 身份验证处理程序在用户成功通过 OpenIDConnect 处理程序进行身份验证(被质询)后创建。

如果 cookie 过大,则会将其分成 4Kb 的块,以确保 cookie 不会被浏览器或代理拒绝。

cookie 中的数据使用Data Protection API 加密,您可以使用数据保护 API 解密 cookie 的内容。

cookie 中的数据主要包含您的 ClaimsPrincipal(用户对象)及其各种声明。或者,您还可以将 openid-connect 令牌存储在 cookie 中。

希望这能回答您的问题。

【讨论】:

以上是关于ASP.NET Core 5 OpenIdConnect 身份验证 cookie 在理论上是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 5 改名 ASP.NET Core 1.0

带有 EF Core 和 CosmosDB .NET 5 的 ASP.Net Core - IdentityRole 问题

小5聊asp.net和asp.net core不同点积累

如何按照存储库模式在 Asp.Net Core 5.0 项目上实现 .Net Core Identity?

.NET 6 Preview 5 中的 ASP.NET Core 更新

从 ASP.NET Core 3.1 升级到 ASP.NET 5.0 后,User.Claims 为空