问题描述
我想在身份"生成的Cookie中保存一些内容.我目前正在使用文档中的默认身份设置.
I want to save something inside my 'Identity' generated cookie. I'm currently using the default Identity setup from the Docs.
Startup.cs
Startup.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
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. 信息"变量为空.
It seems this doesn't work. Because the cookie isn't created yet. The 'Info' variable is empty.
我可以使用"CookieMiddleware"解决它
I could solve it by using the 'CookieMiddleware'
Startup.cs
Startup.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>);
在这种情况下,我需要为自己建立一个用户主体".而且我更喜欢利用身份"解决问题.
In this case I need to build myself a 'user principal'. And I prefer to leverage 'Identity' for this matter.
那么有可能将其结合起来吗?如果不是这种情况,我该如何很好地生成索赔原则.
So is it possible to combine this?If this is not the case how do I generate the claimsprincipal on a good way.
无需映射"每个声明.
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类型.
This doesn't work because user.Claims is of type IdentityUserClaim and not of type Security.Claims.Claim.
感谢您的阅读.祝你有美好的一天,
Thanks for reading.Have a good day,
此致布雷希特
推荐答案
我设法解决了我的问题.
I managed to solve my problem.
我编写了与'signInManager'内部相同的功能.但是要添加我自己的身份验证属性.
I wrote the same functionality that is inside the 'signInManager'. But adding my own authentication property.
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中保存了一些东西(令牌)的代码:
Code that actually saves something (tokens) inside the 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);
}
最后四行代码是最重要的.
The last 4 lines of code are the most important ones.
这篇关于使用ASP.NET Core Identity将令牌保存在Cookie中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!