0

this has been bugging me and I can't find the cause with my lack of knowledge.

below is a success request in postman, the right side is the c# code for it. I also got success result in swagger. enter image description here

however, I keep on getting Unauthorized response enter image description here

Same with restsharp enter image description here

Token has been validated and correct

Tried ChatGPT, but all suggestions have the same result.

WebAPI Program.cs

    // JWT configuration
    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            //options.RequireHttpsMetadata = false;
            //options.SaveToken = true;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = "your_issuer",
                ValidAudience = "your_audience",
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("e91ec378-3c0f-4a32-98d1-573f158eb12a"))
            };
        });
    builder.Services.AddAuthorization(options =>
    {
        options.AddPolicy(IdentityData.AdminPolicyName, policy =>
        {
            policy.RequireAuthenticatedUser();
            policy.RequireClaim(IdentityData.AdminUserClaimName, "ADMN");
        });
    });

    //....

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

Controller

    [ApiController]
    [Route("api/[controller]")]
    public class UserController : ControllerBase
    {
        [Authorize]
        [HttpPost("Authenticate")]
        [ProducesResponseType(typeof(ReturnObject), (int)HttpStatusCode.OK)]
        public ActionResult<ReturnObject> Authenticate([FromBody] RequestObject body)
        {
        }
    }

Edit This is the code for generating JWT


[AllowAnonymous]
[HttpPost("GenerateToken")]
public IActionResult GenerateToken([FromBody] IdentityClaims request)
{
    var claims = new[]
    {
        new Claim(ClaimTypes.Name, request.Username),
        new Claim(ClaimTypes.Email, request.Email),
        new Claim("Role", request.Role)
    };

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("e91ec378-3c0f-4a32-98d1-573f158eb12a"));
    var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: "your_issuer",
        audience: "your_audience",
        claims: claims,
        expires: DateTime.Now.AddDays(1),
        signingCredentials: credentials
    );

    var tokenString = new JwtSecurityTokenHandler().WriteToken(token);

    return Ok(new { Token = tokenString });
}

Got the same Unauthorize for the GetUser, but success in Postman and Swagger enter image description here postman enter image description here swagger (bearer token in the Authorize option) enter image description here

markflo18
  • 1
  • 2
  • See this link: https://stackoverflow.com/questions/11400879/how-to-post-request-using-restsharp – SoftwareDveloper Jun 03 '23 at 20:24
  • Seems like the request from the HttpClient was sent to a https endpoint as shown in the debugging overlay (`https://localhost:7162/...` instead of the specified `http://localhost:5081/...`). – johnmoarr Jun 04 '23 at 08:21

2 Answers2

0

You have an [Authorize] attribute on your Authenticate() endpoint. Change this to [AllowAnonymous].

[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
    [AllowAnonymous]             // <-- Right here
    [HttpPost("Authenticate")]
    [ProducesResponseType(typeof(ReturnObject), (int)HttpStatusCode.OK)]
    public ActionResult<ReturnObject> Authenticate([FromBody] RequestObject body)
    {
    }
}

Since this is the endpoint you are calling to authenticate a user, it must allow anonymous/unauthenticated requests.

Also, you may need to post your code for generating your JWT:

  • Since you are validating issuer/audience, are you pulling these values from IConfiguration, so the JWT is generated with the expected values which are you are validating against?
  • Same for the JWT lifetime, though from your code it does not appear you are validating any lifetime. If you are though, and this just not in the snippet, be sure to check your system clock and consider adding a small clock skew to the JWT validation.
Brian
  • 315
  • 5
  • 10
  • Hi @Brian I've edited my question to include generation of JWT and other method. Indeed Authorize should allowanonymous, I only use it as sample. But I got the same Unauthorize result even for Get and other endpoints. I added a screenshot for GetUser. What I don't get is, it's working in Postman and Swagger but not in app calling the endpoint. btw, the caller is a winui3 app and I used the code generated by postman to call the endpoint. – markflo18 Jun 04 '23 at 00:22
  • Hi @markflo18, have a look at https://github.com/CodeFontana/ApiAuthDemos, the JwtAuthDemo project. See if comparing this API demo is helpful in troubleshooting your project. – Brian Jun 04 '23 at 19:56
0

gotta answer my own question. I fixed this issue a while back by using the https URL instead of http even when http works perfectly using postman.

markflo18
  • 1
  • 2