Search code examples
authenticationjwtasp.net-core-identityasp.net-core-8

Authorize not working in API with ASP.NET Core Identity and JWT Token


I need emergency nelp ... I'm using ASP.NET Core 8.0 and this is my Program.cs:

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer(); 
builder.Services.AddSwaggerGen();   
builder.Services.AddDbContext<Context>
             (optn => optn.UseSqlServer(builder.Configuration.GetConnectionString("SqlServer")));
builder.Services.AddIdentity<UserIdentityCustom,IdentityRole>(opt =>
        {
            opt.User.RequireUniqueEmail = true; //eror
            opt.Lockout.DefaultLockoutTimeSpan = new TimeSpan(100, 1, 1, 1);
            opt.SignIn.RequireConfirmedPhoneNumber = false;
            opt.SignIn.RequireConfirmedEmail = false;               
        })  
            .AddEntityFrameworkStores<Context>()                                      
            .AddDefaultTokenProviders();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(option =>
        {
            option.SaveToken = true;
            option.TokenValidationParameters = new TokenValidationParameters
            {
                RequireExpirationTime = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey  
                (Encoding.UTF8.GetBytes(builder.Configuration["JWT:IssuerSigningKey"]))
            };
        });

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.Run();

This is my controller and action method (have [Authorize]):

[ApiController]
[Route("[controller]")]
public class UploadController : ControllerBase
{
    [Authorize]
    [HttpPost("[action]")]
    public IActionResult Uploadtest()
    {
        return Ok("Uploaded !");
    }
}

The JWT token will be created by this action method:

public async Task<IActionResult> Login([FromBody] UsersLoginModel model) 
{
    if (ModelState.IsValid) 
    {        
        ResultIdentity = True; //ResultIdentity = Check By UserMannager

        if (ResultIdentity.Succeeded == true) 
        {
            var key = _config["JWT:IssuerSigningKey"]; 
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
            var tokenObject = new JwtSecurityToken(
                claims: new List<Claim>() {new Claim("id", model.Username)},
                expires: DateTime.Now.AddMinutes(10),
                signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256));

            var ResultJwt = new JwtSecurityTokenHandler().WriteToken(tokenObject);

            if (ResultJwt == null) 
                return Unauthorized();

            return Ok(ResultJwt);
        }
    }

    return Unauthorized();
}

The response is always an error HTTP 404 or HTTP 302 (I tested in TalentApiTester - Swagger - Postman...)

What is the problem? I tried for 5 hours...

This is my test :

enter image description here


Solution

  • I add "Issuer","Audience" in Jwt, have a try to modify the code like below:

    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(option =>
            {
                option.SaveToken = true;
                option.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidIssuer = builder.Configuration["Jwt:Issuer"],
                    ValidAudience = builder.Configuration["Jwt:Audience"],
                    RequireExpirationTime = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey  
                    (Encoding.UTF8.GetBytes(builder.Configuration["JWT:IssuerSigningKey"]))
                };
            });
    

    Then modify like below :

    public async Task<IActionResult> Login([FromBody] UsersLoginModel model) {
        if (ModelState.IsValid) 
        {        
            ResultIdentity = True; //ResultIdentity = Check By UserMannager
            if (ResultIdentity.Succeeded == true) 
            { 
                var issuer =  _config["Jwt:Issuer"];
                var audience =  _config["Jwt:Audience"];
                var key = _config["JWT:IssuerSigningKey"]; 
                var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
     var tokenDescriptor = new SecurityTokenDescriptor
     {
         Subject = new ClaimsIdentity(new[]
         { new Claim("id", model.Username) 
         }),
         Expires= DateTime.Now.AddMinutes(10),
         Issuer = issuer,
         Audience = audience,
         SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256)
         
     };
     var tokenObject = new JwtSecurityTokenHandler().CreateToken(tokenDescriptor);
                var ResultJwt = new JwtSecurityTokenHandler().WriteToken(tokenObject);
                if (ResultJwt == null) return Unauthorized();
                return Ok(ResultJwt);
            }
           
        }
        return Unauthorized();
    }
    

    result: enter image description here