I am trying to build a very simple playground server for me to study some ASP.NET Core authentication/authorization concepts. Basically a web app with a single, very simple controller, to be tested with Postman.
I came up with a minified version of my code, consisting of a single login endpoint which would authenticate the user (no credentials required) using Cookie Authentication, like that:
[ApiController]
public class MyController : ControllerBase
{
[HttpGet("/login")]
public async Task<IActionResult> Login()
{
var claims = new[] { new Claim("name", "bob") };
var identity = new ClaimsIdentity(claims);
var principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(principal);
return Ok();
}
}
The thing is that the call to HttpContext.SignInAsync()
is firing the following exception:
System.InvalidOperationException: SignInAsync when principal.Identity.IsAuthenticated is false is not allowed when AuthenticationOptions.RequireAuthenticatedSignIn is true.
at Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext context, String scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
at MyController.Login() in C:UsersvinicDesktopTEMPTestesAuthorizationControllersMyController.cs:line 18
Then I tried to replace HttpContext.SignInAsync()
by a call to HttpContext.AuthenticateAsync()
, so that I could authenticate the user before trying to call SignInAsync()
again:
[HttpGet("/login")]
public async Task<IActionResult> Login()
{
var authResult = await HttpContext.AuthenticateAsync();
if (authResult.Succeeded == false)
return StatusCode(500, "Failed to autenticate!");
return Ok();
}
But in that case the AuthenticateAsync()
result always returns a failure (authResult.Succeeded
= false), and later calls to HttpContext.SignInAsync()
would fail with the same InvalidOperationException as before. By enabling "Trace"-level logging, the call to AuthenticateAsync() only logs the following (not very helpful) piece of information:
dbug: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9]
AuthenticationScheme: Cookies was not authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Debug: AuthenticationScheme: Cookies was not authenticated.
My project targets the net5.0
framework, has no external/explicit dependencies, and here's the Startup class I'm using:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IConfiguration configs)
{
app.UseRouting();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
I know I must be missing something really basic here. I'm also not sure if the documentation I am basing myself on is actually up-to-date for .NET 5.0.
Why is the cookie authentication (HttpContext.SignInAsync()
/ HttpContext.AuthenticateAsync()
) failing?