问题描述
我有一个简单的控制器,在用户登录后调用.我可以在我的身份服务器上看到用户已登录.我还可以看到浏览器中设置了 .AspNetCore.Identity.Application cookie.
I have a simple controller which is called after the user logs in. I can see on my identity server that the user is logged in. I can also see that .AspNetCore.Identity.Application cookie is set in the browser.
登录后,使用
RedirectToAction(nameof(Index), "Manage")
问题是控制器似乎没有经过身份验证.我已经尝试过 HttpContext.User 以及我认为控制器没有读取 cookie 的所有其他内容
The problem is that the controller doesn't appear to be authenticated. I have tried HttpContext.User and everything else i can think the controller isn't reading the cookie
[Authorize]
[Route("[controller]/[action]")]
public class ManageController : Controller
{
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Index(ManageMessageId? message = null)
{
// try to find user here.
}
}
我找到了一种强制它加载 cookie 的方法
I have found a work around which forces it to load the cookie
var loadTheStupidCookie = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
var user = await _userManager.GetUserAsync(loadTheStupidCookie.Principal);
这可行,但我认为必须在控制器的每个方法中加载它都过头了.控制器不应该能够为我加载cookie吗?
This works but I think its over kill to have to load it in every method in the controller. Shouldn't the controller be able to load the cookie for me?
来自startup.cs
From startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
options.AccessDeniedPath = new PathString("/Account/Forbidden/");
})
.AddGoogle("Google", options =>
{
options.AccessType = "offline";
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "xxxxx.apps.googleusercontent.com";
options.ClientSecret = "XXXX";
});
注意:删除 [AllowAnonymous] 会导致它根本不起作用,可能是因为它看不到身份验证.
Note: Removing [AllowAnonymous] causes it to not work at all probably due to the fact that it cant see the authentication.
推荐答案
当您使用 Authorize
属性时,它将使用使用 AddAuthentication 配置的默认
AuthenticationScheme
代码>.在您的示例中,它看起来像这样:
When you use the Authorize
attribute, it will use the default AuthenticationScheme
configured using AddAuthentication
. In your example, that looks like this:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
因为这是CookieAuthenticationDefaults.AuthenticationScheme
("Cookies"),Authorize
属性在尝试登录用户时使用它.您的解决方法表明您实际上想要使用 IdentityConstants.ApplicationScheme
("Identity.Application")` 代替.
Because this is CookieAuthenticationDefaults.AuthenticationScheme
("Cookies"), the Authorize
attribute is using that when attempting to sign the user in. Your workaround shows that you actually wanted to use IdentityConstants.ApplicationScheme
("Identity.Application")` instead.
Authorize
属性允许您使用 AuthenticationSchemes
属性指定要使用的 AuthenticationScheme
(s),如下所示:
The Authorize
attribute allows you to specify the AuthenticationScheme
(s) you want to use, using the AuthenticationSchemes
property, which looks like this:
[Authorize(AuthenticationSchemes = "Identity.Application")]
事实证明您不能直接使用 IdentityConstants.ApplicationScheme
,因为这不是编译时常量.虽然您可以显式使用字符串值,但您可以通过设置策略来获得编译时安全,例如.请参阅 docs 有关如何执行此操作的示例.
It turns out you can't use IdentityConstants.ApplicationScheme
directly, as this is not a compile-time constant. Although you could use the string value explicitly, you can get the compile time safety by setting up a policy, for example. See the docs for an example on how to do that.
这篇关于控制器未加载 .AspNetCore.Identity.Application 用户 cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!