gpt4 book ai didi

c# - 为什么 Authentication Cookie 对 [Authorize] 属性不起作用?

转载 作者:行者123 更新时间:2023-12-01 21:25:36 25 4
gpt4 key购买 nike

我们尝试在我们的 Blazor-WebAssembly 应用中通过 Cookie 实现身份验证。

Controller :设置 Auth-Cookie:

[Route("[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
[HttpPost]
public async Task<AdUser> Login(Credentials pCredentials)
{
// [...] credential check jere

var lClaims = new List<Claim> {
new Claim(ClaimTypes.Name, "SamAccountName"),
};
var lClaimsIdentity = new ClaimsIdentity(lClaims, CookieAuthenticationDefaults.AuthenticationScheme);

// set cookie
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(lClaimsIdentity),
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddYears(1),
RedirectUri = this.Request.Host.Value
});

// [...]
}
}

当我查看边缘浏览器的开发人员工具时,我发现 cookie 已设置:

enter image description here

现在下面的 Controller 有一个 Search-Action 并且应该通过添加 [Authorize] 属性来限制访问:

[Route("[controller]")]
[ApiController]
public class ClientsController : ControllerBase
{
[HttpGet("search")]
[Authorize]
public ActionResult<List<Shared.Client>> Search(string pText)
{
// [...] Code here

return lResult;
}
}

当我对 ClientsController 执行 HTTP 请求 /Clients?search=My Search Text 时,Edge 的开发人员工具向我显示了对 /Account 的请求/登录。这让我感到困惑,因为响应代码是 200,但我的项目中不存在帐户 Controller 。

为什么我的身份验证 Cookie 不能针对 [Authorize] 属性工作?

enter image description here

关于我的配置的一些进一步细节:

Startup.cs(服务器端)

namespace BlazorWebAssemblyApp.Server
{
public class Startup
{
/// [...]

public void ConfigureServices(IServiceCollection services)
{
// [...]
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(); // This line is required for the authentication cookie
// [...]
}
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// [...]

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}
}

最佳答案

如果您在使用 cookie 身份验证方案显式登录后发现用户在以后的请求中无法被识别,则表明您没有正确配置身份验证中间件。作为per the docs ,您不仅必须使用 services.AddAuthentication(...) 添加身份验证服务,还必须配置身份验证中间件作为请求管道的一部分运行。这通常看起来像这样:

app.UseRouting();

// add the call to `UseAuthentication`
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});

通过将 UseAuthentication() 调用添加到中间件中,您将导致默认身份验证方案(在您的情况下为 cookie 方案)尝试对用户进行身份验证。这确保如果请求中有身份验证 cookie,那么它将用于对用户进行身份验证,无论您是否要访问授权路由。

一旦中间件运行,仅受 [Authorize] 属性保护的操作也将起作用,因为 cookie 方案的身份验证已经发生(因为它是默认方案)。

否则,如果默认情况下不调用中间件,则需要确保在需要访问用户信息时始终显式调用身份验证方案。这就是 [Authorize(AuthenticationSchemes = "scheme-name")] 所做的:在 authorization 运行之前,它将尝试验证指定的方案。 – 如果您使用身份验证中间件并且具有正确的默认方案,那么您可以跳过此步骤,因为该方案将默认进行身份验证。

在您的原始代码中,没有运行身份验证,这也解释了您被重定向的原因:由于身份验证方案未运行以对用户进行身份验证,因此没有登录用户(即使用户有一 block cookies )。因此,当用户被授权时,那里没有用户,您将被重定向到登录页面。

为什么会重定向到/Account/Login

cookie 身份验证方案涉及在需要身份验证(例如通过 [Authorize] 属性)但用户还没有身份验证 cookie 时将用户重定向到登录页面。在这种情况下,身份验证将受到“挑战”,对于 cookie 方案而言,这意味着用户将被重定向到他们应该登录的登录页面。

默认情况下,登录页面的路由配置为/Account/Login。当您使用 ASP.NET Core Identity 时,此默认值与默认行为相匹配。您可以通过更改 CookieAuthenticationOptions.LoginPath 轻松配置此路由以匹配您的实际登录页面.例如,您可以使用 AddCookie() 调用来做到这一点:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Auth/Login"; // using the AuthController instead
});

现在,当用户受到挑战时,他们将被重定向到您的 AuthController.Login 操作,而不是他们应该登录的地方。

请注意,cookie 方案将向登录操作添加一个请求参数 ReturnUrl,其中包含用户最初尝试访问的页面的路径。例如。当访问您的搜索操作时,他们将被重定向到 /Auth/Login?ReturnUrl=%2FClients%2Fsearch。所以你应该接受这个路由参数并在登录完成后返回到那个路由,例如:

[HttpPost]
public async Task<IActionResult> Login(Credentials pCredentials, string returnUrl)
{
// do login

return LocalRedirect(returnUrl);
}

您还可以通过更改 CookieAuthenticationOptions.ReturnUrlParameter 将参数 ReturnUrl 的名称更改为任何您喜欢的名称.

关于c# - 为什么 Authentication Cookie 对 [Authorize] 属性不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63188383/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com