Search code examples
jwtclaims-based-identityclaims.net-core-2.0

Generating a JWT token using AuthenticateAsync


I am trying to login using ClaimsPrincipal and then fetch a JWT in .net core 2.0. With my current code, I get the error from the result of the SignInAsync function: "No IAuthenticationSignInHandler is configured to handle sign in for the scheme: Bearer"

Here is the controller I am currently using:

[Route("Login/{username}")]
public async Task<IActionResult> Login(string username)
{
    var userClaims = new List<Claim>
    {
        new Claim(ClaimTypes.Name, username)
    };
    var principal = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
    var sign = HttpContext.SignInAsync(principal);
    await sign;
    var res = await HttpContext.AuthenticateAsync();
    var token = await HttpContext.GetTokenAsync("access_token");
    return Json(token);
}

The login portion was tested and works well with cookies. However when I use the following code with JwtBearerDefaults.AuthenticationScheme in my startup.cs:

services.AddAuthentication(config => {
    config.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    config.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(config =>
{
    config.TokenValidationParameters = Token.tokenValidationParameters;
    config.RequireHttpsMetadata = false;
    config.SaveToken = true;
});

I get the error from the result of the SignInAsync function: "No IAuthenticationSignInHandler is configured to handle sign in for the scheme: Bearer"

My Token class was created with the help of a code I found online (at JWT on .NET Core 2.0) and is defined as follows:

public static class Token
{

    public static TokenValidationParameters tokenValidationParameters {
        get
        {

            return new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = GetSignInKey(),
                ValidateIssuer = true,
                ValidIssuer = GetIssuer(),
                ValidateAudience = true,
                ValidAudience = GetAudience(),
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
            };
        }
    }

    static private SymmetricSecurityKey GetSignInKey()
    {
        const string secretKey = "very_long_very_secret_secret";
        var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));

        return signingKey;
    }

    static private string GetIssuer()
    {
        return "issuer";
    }

    static private string GetAudience()
    {
        return "audience";
    }

}

Solution

  • A signed token can be created using the JwtSecurityTokenHandler.

    var handler = new JwtSecurityTokenHandler();
    var jwt = handler.CreateJwtSecurityToken(new SecurityTokenDescriptor
    {
         Expires = DateTime.UtcNow.Add(Expiary),
         Subject = new ClaimsIdentity(claims, "local"),
         SigningCredentials = new SigningCredentials(SigningKey, SecurityAlgorithms.HmacSha256)
    });
    return handler.WriteToken(jwt);