Sim*_*mon 2 c# asp.net-core asp.net-core-webapi blazor blazor-webassembly
我们尝试在 Blazor-WebAssembly 应用程序中通过 Cookie 实现身份验证。
控制器:设置 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
});
// [...]
}
}
Run Code Online (Sandbox Code Playgroud)
当我查看边缘浏览器的开发人员工具时,我看到的 cookie 已设置:
现在下面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;
}
}
Run Code Online (Sandbox Code Playgroud)
当我/Clients?search=My Search Text向 ClientsController发出 HTTP 请求时,Edge 的开发人员工具向我显示,有一个对/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");
});
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在使用 cookie 身份验证方案显式登录后发现在以后的请求中无法识别用户,则表明您没有正确配置身份验证中间件。根据文档,您不仅需要添加身份验证服务,services.AddAuthentication(…)还必须配置身份验证中间件作为请求管道的一部分运行。这通常如下所示:
app.UseRouting();
// add the call to `UseAuthentication`
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Run Code Online (Sandbox Code Playgroud)
通过将UseAuthentication()调用添加到中间件中,您将导致默认身份验证方案(在您的情况下为 cookie 方案)尝试对用户进行身份验证。这确保如果请求中存在身份验证 cookie,那么它将用于对用户进行身份验证,无论您是否要访问授权路由。
一旦中间件运行,仅使用该[Authorize]属性保护的操作也将起作用,因为 cookie 方案的身份验证已经发生(因为它是默认方案)。
否则,如果默认情况下不调用中间件,则需要确保在需要访问用户信息时始终显式调用身份验证方案。这就是这样[Authorize(AuthenticationSchemes = "scheme-name")]做的:在授权运行之前,它将尝试对指定的方案进行身份验证。– 如果您使用身份验证中间件并具有正确的默认方案,那么您可以跳过此步骤,因为该方案将默认进行身份验证。
在您的原始代码中,如果没有运行身份验证,这也解释了您被重定向的原因:由于身份验证方案未运行以对用户进行身份验证,因此没有登录用户(即使用户有 cookie) . 所以当用户被授权时,没有用户在那里,你被重定向到登录页面。
/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
});
Run Code Online (Sandbox Code Playgroud)
现在,当用户受到挑战时,他们将被重定向到您的AuthController.Login操作,而不是他们应该登录的位置。
请注意,cookie 方案将向ReturnUrl登录操作添加一个请求参数,其中包含用户最初尝试访问的页面的路径。例如,在访问您的搜索操作时,它们将被重定向到/Auth/Login?ReturnUrl=%2FClients%2Fsearch. 因此,您应该接受此路由参数并在登录完成后返回该路由,例如:
[HttpPost]
public async Task<IActionResult> Login(Credentials pCredentials, string returnUrl)
{
// do login
return LocalRedirect(returnUrl);
}
Run Code Online (Sandbox Code Playgroud)
您还可以ReturnUrl通过更改CookieAuthenticationOptions.ReturnUrlParameter.
| 归档时间: |
|
| 查看次数: |
1490 次 |
| 最近记录: |