本文介绍了控制器未加载 .AspNetCore.Identity.Application 用户 cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的控制器,在用户登录后调用.我可以在我的身份服务器上看到用户已登录.我还可以看到浏览器中设置了 .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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 03:15