使用 ASP.NET Core Identity 将令牌保存在 Cookie 中

2024-04-29

我想在我的“身份”生成的 cookie 中保存一些内容。我目前正在使用文档中的默认身份设置。

启动.cs

services.Configure<IdentityOptions>(options =>
{
    // User settings
    options.User.RequireUniqueEmail = true;

    // Cookie settings
    options.Cookies.ApplicationCookie.AuthenticationScheme = "Cookies";
    options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromHours(1);
    options.Cookies.ApplicationCookie.SlidingExpiration = true;
    options.Cookies.ApplicationCookie.AutomaticAuthenticate = true;
    options.Cookies.ApplicationCookie.LoginPath = "/Account";
    options.Cookies.ApplicationCookie.LogoutPath = "/Account/Logout";
});

AccountController.cs

var result = await _signInManager.PasswordSignInAsync(user.UserName, model.Password, true, true);

if (result.Succeeded)
{
    _logger.LogInformation(1, "User logged in.");

    var tokens = new List<AuthenticationToken>
    {
        new AuthenticationToken {Name = "Test", Value = "Test"},
    };


    var info = await HttpContext.Authentication.GetAuthenticateInfoAsync("Cookies");
    info.Properties.StoreTokens(tokens);

看来这行不通。因为cookie还没有创建。 “信息”变量为空。

我可以通过使用“CookieMiddleware”来解决它

启动.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = "Cookies",
    ExpireTimeSpan = TimeSpan.FromHours(1),
    SlidingExpiration = true,
    AutomaticAuthenticate = true,
    LoginPath = "/Account",
    LogoutPath = "/Account/Logout",
});

但比我需要使用

await HttpContext.Authentication.SignInAsync("Cookies", <userPrincipal>);

在这种情况下,我需要为自己建立一个“用户主体”。我更喜欢在这件事上利用“身份”。

那么是否可以将其结合起来呢? 如果不是这种情况,我该如何以良好的方式生成索赔主体。

无需“绘制”每项索赔。

List<Claim> userClaims = new List<Claim>
{
    new Claim("UserId", Convert.ToString(user.Id)),
    new Claim(ClaimTypes.Name, user.UserName),
    // TODO: Foreach over roles
};

ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
await HttpContext.Authentication.SignInAsync("Cookies", principal);

所以像这样:

ClaimsPrincipal pricipal = new ClaimsPrincipal(user.Claims); 

这不起作用,因为 user.Claims 的类型为 IdentityUserClaim,而不是 Security.Claims.Claim 类型。

谢谢阅读。 祝你有美好的一天,

此致,布莱希特


我设法解决了我的问题。

我在“signInManager”中编写了相同的功能。但添加我自己的身份验证属性。

var result = await _signInManager.PasswordSignInAsync(user, model.Password, true, true);
if (result.Succeeded)
{
    await AddTokensToCookie(user, model.Password);
    return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
    // Ommitted
}
if (result.IsLockedOut)
{
    // Ommitted
}

实际上在 cookie 中保存某些内容(令牌)的代码:

private async Task AddTokensToCookie(ApplicationUser user, string password)
{
    // Retrieve access_token & refresh_token
    var disco = await DiscoveryClient.GetAsync(Environment.GetEnvironmentVariable("AUTHORITY_SERVER") ?? "http://localhost:5000");

    if (disco.IsError)
    {
        _logger.LogError(disco.Error);
        throw disco.Exception;
    }

    var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
    var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync(user.Email, password, "offline_access api1");

    var tokens = new List<AuthenticationToken>
    {
        new AuthenticationToken {Name = OpenIdConnectParameterNames.AccessToken, Value = tokenResponse.AccessToken},
        new AuthenticationToken {Name = OpenIdConnectParameterNames.RefreshToken, Value = tokenResponse.RefreshToken}
    };

    var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn);
    tokens.Add(new AuthenticationToken
    {
        Name = "expires_at",
        Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
    });

    // Store tokens in cookie
    var prop = new AuthenticationProperties();
    prop.StoreTokens(tokens);
    prop.IsPersistent = true; // Remember me

    await _signInManager.SignInAsync(user, prop);
}

最后 4 行代码是最重要的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ASP.NET Core Identity 将令牌保存在 Cookie 中 的相关文章

随机推荐