我正在尝试创建自己的登录身份验证,但是该身份验证无法正常工作,因此我创建了此快速测试...
[HttpGet]
public IActionResult Index()
{
try
{
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.Name, "Test Name"));
var principal = new ClaimsPrincipal(identity);
SignIn(principal, CookieAuthenticationDefaults.AuthenticationScheme);
var isAuthenticated = User.Identity.IsAuthenticated; //-- THIS IS ALWAY FALSE... BUI JUST LOGGED IN?!?!?!?
return View();
}
catch(Exception ex)
{
_logger.LogError(ex, "Error:");
return StatusCode(500);
}
}
因此您可以看到我呼叫SignIn
,然后在下一行中检查用户是否已通过身份验证,但它始终返回false,并且User.Identity
看上去也为空。有人知道我在做什么错吗?
在我的Startup / ConfigureServices中,我有:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(
CookieAuthenticationDefaults.AuthenticationScheme,
options =>
{
options.LoginPath = "/Admin/Index";
});
然后在“启动/配置”中
app.UseAuthentication();
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
});
答案 0 :(得分:1)
SignIn(principal, CookieAuthenticationDefaults.AuthenticationScheme);
这是无人操作。 SignIn
是一种创建SignInResult
实例的便捷方法,通常会从操作中返回。这遵循命令模式,但是您的示例仅创建命令而从不执行。
您真正想要的是以下内容:
await HttpContext.SignInAsync(principal);
您可以根据需要提供该方案,但是您已将CookieAuthenticationDefaults.AuthenticationScheme
中的ConfigureServices
设置为默认方案,因此可以假定。
但是,即使进行了此更改,在提出另一个请求之前,User.Identity.IsAuthenticated
仍将是false
。通常,您会执行以下操作:
await HttpContext.SignInAsync(principal);
return RedirectToAction(...);
在设置后,调用SignInAsync
最终将创建一个存储身份验证信息的cookie。它不会更新当前的User
。在由重定向引起的下一个请求中,您的ASP.NET Core应用将读取cookie,并正确填充User
。
答案 1 :(得分:0)
我看到您的Index
方法缺少Authorize
属性。请添加Authorize
属性,如下所示:
[Authorize]
[HttpGet]
public IActionResult Index()
{
....
}
然后在Configure
类的Startup
方法中,中间件顺序应如下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
......
app.UseStaticFiles();
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
});
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
现在它应该对您有用。
答案 2 :(得分:0)
这是SignIn
public virtual SignInResult SignIn(
ClaimsPrincipal principal,
string authenticationScheme)
=> new SignInResult(authenticationScheme, principal);
以上代码仅返回对象SignInResult
,该对象此时不执行任何操作。
这是SignInResult
的源代码:
https://github.com/aspnet/Mvc/blob/master/src/Microsoft.AspNetCore.Mvc.Core/SignInResult.cs
这是核心代码:
public class SignInResult : ActionResult
{
/// <inheritdoc />
public override async Task ExecuteResultAsync(ActionContext context)
{
...
await context.HttpContext.SignInAsync(AuthenticationScheme, Principal, Properties);
}
}
这是一个返回类型ActionResult
,它只是调用context.HttpContext.SignInAsync
,因此ControllerBase.SignIn
是HttpContext.SignInAsync()
的一种快捷方式。
但是!看一下以下ActionResult
:
public abstract class ActionResult : IActionResult
{
public virtual Task ExecuteResultAsync(ActionContext context)
{
this.ExecuteResult(context);
return Task.CompletedTask;
}
public virtual void ExecuteResult(ActionContext context)
{
}
}
因此SignInResult
在Sync
方法上什么也不做,而只在Async
上做。
我可以建议的是:
return SignIn(...)
,然后该操作将自动执行,然后您可以在下一个请求中检查其授权。HttpContext.SignInAsync()
,它是当前代码。SignInResult
实现的async
函数,但是在sync
方法中什么也不做,因此您可以尝试将测试操作更改为{ {1}}