我们试图通过Cookies在我们的Blazor-WebAssembly应用程序中实现身份验证。
控制器:设置8月饼干:
[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已经设置好了:

现在,下面的Controller具有一个搜索-操作,并且应该通过添加授权属性来限制访问:
[Route("[controller]")]
[ApiController]
public class ClientsController : ControllerBase
{
[HttpGet("search")]
[Authorize]
public ActionResult<List<Shared.Client>> Search(string pText)
{
// [...] Code here
return lResult;
}
}当我对/Clients?search=My Search Text执行HTTP时,边缘的开发人员工具告诉我,有一个对/Account/Login的请求。这让我很困惑,因为响应代码是200,但在我的项目中不存在Account-Controller。
为什么我的身份验证Cookie不针对[Authorize] 属性工作?

关于我的配置的一些更详细的信息:
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");
});
}
}发布于 2020-07-31 09:21:46
如果您看到在您使用cookie身份验证方案显式登录之后,在未来的请求中无法识别用户,那么这说明您没有正确地配置身份验证中间件。作为按照医生的说法,您不仅必须使用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")]所做的:在授权运行之前,它将尝试对指定的方案进行身份验证。-如果您使用身份验证中间件,并且有正确的默认方案,那么您可以跳过这一点,因为该方案将在默认情况下进行身份验证。
在原始代码中,如果不运行身份验证,这也会给出为什么要重定向的解释:由于身份验证方案不是为了验证用户而运行的,所以用户中没有签名(即使用户有cookie)。因此,当用户被授权时,没有用户在场,而您被重定向到登录页面。
为什么要重定向到/Account/Login
cookie身份验证方案是在需要身份验证时(例如通过[Authorize]属性)将用户重定向到登录页面的方案,但用户还没有身份验证cookie。在这种情况下,身份验证将受到“挑战”,对于cookie方案来说,这意味着用户将被重定向到登录页面,在那里他们应该登录。
默认情况下,登录页的路由配置为/Account/Login。在使用ASP.NET核心标识时,此默认值与默认行为相匹配。通过更改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);
}还可以通过更改ReturnUrl,将参数CookieAuthenticationOptions.ReturnUrlParameter的名称更改为任何您喜欢的名称。
发布于 2020-07-31 10:09:57
您将被重定向到“登录页”(Login)或returnURL,因为您的身份验证工作不正常,而且未经授权。默认情况下,当ASP.Net核心无法验证而不是返回401代码时,它会重定向您。
确保您正在以正确的方式实现它,如https://learn.microsoft.com/es-es/aspnet/core/security/authentication/identity?view=aspnetcore-3.1&tabs=visual-studio中所述。
不要忘记在Startup.cs类中的配置方法中添加以下行来添加auth中间件:
app.UseAuthentication();
app.UseAuthorization();请检查您是否有正确的顺序。(顺序很重要,因为您首先验证,然后它检查您的角色)。
它们还必须放在app.UseRouting()和app.UseEndpoints()调用之间。
发布于 2020-07-31 11:41:29
我自己得到了它,使用[Authorize(AuthenticationSchemes = AuthSchemes)] fpr我在控制器中的动作。以下是代码:
[Route("[controller]")]
[ApiController]
public class ClientsController : ControllerBase
{
private const string AuthSchemes = CookieAuthenticationDefaults.AuthenticationScheme;
[HttpGet("search")]
[Authorize(AuthenticationSchemes = AuthSchemes)]
public ActionResult<List<Shared.Client>> Search(Shared.Client.SearchProperty pProperty, string pText)
{
// [...]
}
}您可以在这里阅读更多有关此主题的内容:https://learn.microsoft.com/de-de/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1
https://stackoverflow.com/questions/63188383
复制相似问题