Ian Kirkpatrick
Ian Kirkpatrick

Reputation: 1960

AspNetCore Default Authorization User not authenticated

Using: dotnet-core 3.1

I have an application where we are trying to add some authentication. Authorization seems to be calling all of our appropriate pieces but still throws an authorization error saying the user is not authenticated.

The user exists in the database and the authentication handler even finishes and does it's thing. But for some reason, they are not being authenticated even though the authentication handler seems to be doing it's thing.

Startup.cs

ConfigureServices(...) {
    services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = "TestScheme";
                sharedOptions.DefaultAuthenticateScheme = "TestScheme";
                sharedOptions.DefaultChallengeScheme = "TestScheme";
        }).AddScheme<TestAuthenticationOptions, TestAuthentication>("TestScheme", options => { });
    services.AddAuthorization();
}

Configure() {
    app.UseMvc();
    app.UseAuthentication();
    app.UseAuthorization();
}

TestAuthentication.cs

protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
    // Get Authorization header value
    if (!this.Request.Headers.TryGetValue(HeaderNames.Authorization, out StringValues authorization))
    {
        return Task.FromResult(AuthenticateResult.Fail("Cannot read authorization header."));
    }

    List<Claim> claims = new List<Claim> {
        new Claim(ClaimTypes.NameIdentifier, authorization.ToString()),
        new Claim(ClaimTypes.Name, authorization.ToString()),
        new Claim(ClaimTypes.Email, authorization.ToString())
    };

    // Create authenticated user
    var ticket = new AuthenticationTicket(new ClaimsPrincipal(new ClaimsIdentity(claims)), "TestScheme");

    return Task.FromResult(AuthenticateResult.Success(ticket));
}

Controller:

public class TestAuthController : Controller
{
  [Authorize]
  public JsonResult Test()
  {
    return new JsonResult(HttpContext.User.Claims.Select(c => c.Type + " - " + c.Value));
  }
}

When I make a call to the endpoint, I get a 401 unauthorized. The log in the server console looks like so:

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET http://localhost:5005/testauth/test  
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.1.0 initialized 'MyAppContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
dbug: MyApp.API.TestAuthentication[8]
      AuthenticationScheme: TestScheme was successfully authenticated.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed.
info: MyApp.API.TestAuthentication[12]
      AuthenticationScheme: TestScheme was challenged.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 2.5679ms 401

Upvotes: 2

Views: 1359

Answers (1)

Ian Kirkpatrick
Ian Kirkpatrick

Reputation: 1960

I realized that the issue was that I was not passing the authentication scheme into the ClaimsIdentity.

So the ticket instantiation in the authentication handler looks like this:

var ticket = new AuthenticationTicket(new ClaimsPrincipal(new ClaimsIdentity(claims, "TestScheme")), "TestScheme");

instead of

var ticket = new AuthenticationTicket(new ClaimsPrincipal(new ClaimsIdentity(claims)), "TestScheme");

Upvotes: 3

Related Questions