c# - HttpContext.SignInAsync() 无法设置 cookie 并返回 User.Claims
问题描述
我写了一个网站,可以从 Discord 执行 SSO。我正在尝试仅通过 cookie 使用登录系统。我似乎无法设置 cookie 并返回 User.Claims。我在下面提供了 Startup.cs 和我的登录文件。预先感谢您。
var tempId = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
tempId.AddClaim(new Claim("state", state));
tempId.AddClaim(new Claim("nonce", nonce));
//HttpContext.Request.GetOwinContext().Authentication.SignIn(tempId);
var authProperties = new AuthenticationProperties
{
AllowRefresh = true,
ExpiresUtc = DateTimeOffset.Now.AddDays(1),
IsPersistent = true,
};
var principal = new ClaimsPrincipal(tempId);
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
var claim = HttpContext.User.Claims;
地位
services.AddSession();
services.Configure<CookiePolicyOptions>(options =>
{
options.ConsentCookie.IsEssential = true;
options.CheckConsentNeeded = context => false;
});
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "Cookie";
options.Cookie.IsEssential = true;
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.LoginPath = new PathString("/account/login");
options.LogoutPath = new PathString("/account/logout");
options.ExpireTimeSpan = TimeSpan.FromDays(1);
options.SlidingExpiration = false;
});
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
}).SetCompatibilityVersion(CompatibilityVersion.Latest); ;
app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
解决方案
正如 abdusco 所说,在 login 方法中,在添加claims
到ClaimsPrincipal
并调用该HttpContext.SignInAsync()
方法登录后,您声称不会在 current 中更新HttpContext.User
。因此,如果您直接从 获得索赔HttpContext.User
,则为空。
如果要访问登录页面中的声明(在调用HttpContext.SignInAsync()
方法之后),可以从 中获取声明principal
,代码如下:
#region snippet1
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
//...
};
var principal = new ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
#endregion
var userclaims = principal.Claims;
结果如下:
如果您想从 中获取声明HttpContext.User
,您应该从下一个请求中获取它们。
请参考cookie认证文档和官方示例代码。
在Login.cshtml.cs 文件的 post 方法中,它将向用户添加声明。
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
ReturnUrl = returnUrl;
if (ModelState.IsValid)
{
// Use Input.Email and Input.Password to authenticate the user
// with your custom authentication logic.
//
// For demonstration purposes, the sample validates the user
// on the email address maria.rodriguez@contoso.com with
// any password that passes model validation.
var user = await AuthenticateUser(Input.Email, Input.Password);
if (user == null)
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
#region snippet1
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
//AllowRefresh = <bool>,
// Refreshing the authentication session should be allowed.
//ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
// The time at which the authentication ticket expires. A
// value set here overrides the ExpireTimeSpan option of
// CookieAuthenticationOptions set with AddCookie.
//IsPersistent = true,
// Whether the authentication session is persisted across
// multiple requests. When used with cookies, controls
// whether the cookie's lifetime is absolute (matching the
// lifetime of the authentication ticket) or session-based.
//IssuedUtc = <DateTimeOffset>,
// The time at which the authentication ticket was issued.
//RedirectUri = <string>
// The full path or absolute URI to be used as an http
// redirect response value.
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
#endregion
_logger.LogInformation("User {Email} logged in at {Time}.",
user.Email, DateTime.UtcNow);
return LocalRedirect(Url.GetLocalUrl(returnUrl));
}
// Something failed. Redisplay the form.
return Page();
}
然后,在联系页面(需要身份验证)中,我们可以从以下位置访问声明HttpContext.Claims
:
推荐阅读
- google-sheets - Get value from ColumnA if rest of row contains (value)
- nginx - 使用 nginx-Ingress 在 Kubernetes 中将 TCP 端口暴露在集群之外
- oracle - Select max value in query for type
- python - 从函数硬编码或变量返回布尔值的最佳实践
- python - Legend location, similar to telephone
- php - 当我们有 API 时发送电子邮件?发送网格
- django - Django url 看不到上下文变量
- swift - 当缩小标记在Swift 4中改变位置时
- python - 首先将二进制字符串转换为base64,然后再转换为图像
- jquery - 如何控制
html标签的工作