Postman returns 401 despite the valid token distributed for a secure endpoint

泪湿孤枕 提交于 2019-12-25 01:14:19

问题


I've set up the authorization like this, loosely following the three blogs here, here and here (basically making it wide open except for the validation of the expiration time).

string secret = "super-secret-password";
byte[] bytes = Encoding.ASCII.GetBytes(secret);
SymmetricSecurityKey key = new SymmetricSecurityKey(bytes);
TokenValidationParameters parameters = new TokenValidationParameters
{
  IssuerSigningKey = key,
  ValidateLifetime = true,
  ValidateIssuerSigningKey = false,
  ValidateIssuer = false,
  ValidateAudience = false,
  RequireAudience = false,
  RequireExpirationTime = false,
  RequireSignedTokens = false
};
services.AddAuthentication(_ => _.DefaultScheme = JwtBearerDefaults.AuthenticationScheme)
  .AddJwtBearer(_ => _.TokenValidationParameters = parameters);

The token distributed is created like this.

string secret = "super-secret-password";
byte[] bytes = Encoding.ASCII.GetBytes(secret);
SymmetricSecurityKey key = new SymmetricSecurityKey(bytes);

Claim[] claims = {
  new Claim("role", "basic"),
  new Claim("role", "elevated"),
  new Claim("name", name)
};

JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor
{
  Subject = new ClaimsIdentity(claims),
  Expires = DateTime.Now.AddHours(1),
  SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature)
};

SecurityToken token = handler.CreateToken(descriptor);
return handler.WriteToken(token);

Then, I paste the returned string into JWT.io and it confirms that everything is great (valid signature and all that). However, when I use that token in Postman (it adds the header Bearer + my_token_string), the call gives me 401 unauthorized.

I tried two secure methods in my controller and one open (the latter works as expected).

[HttpGet("open"), AllowAnonymous]
public ActionResult OpenResult() { return Ok("Open result accessed."); }
[HttpGet("secure"), Authorize]
public ActionResult SecureResult() { return Ok("Secure result accessed."); }
[HttpGet("elevated"), Authorize(Roles = "elevated")]
public ActionResult ElevatedResult() { return Ok("Elevated result accessed."); }

I don't know what I might be missing. Even worse, I'm not sure how to investigate it further.

What can I do at this point?

This answer suggest setting headers. This answer is irrelevant for my relaxed case with no validation of audience. This answer gives nothing much, really. (Just making sure to show that I've done my effort.)


回答1:


One thing to check is the ordering of "use" statements in Configure in Startup.cs. If you have app.UseAuthorization() before app.UseAuthentication() you'll get 401s. This has caught me before:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors("CorsPolicy");

        app.UseRouting();

        app.UseAuthentication(); //make sure this comes before app.UseAuthorization()
        app.UseAuthorization(); 
        app.UseHttpsRedirection();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<NotificationHubService>("/notification");
        });
    }


来源:https://stackoverflow.com/questions/59255124/postman-returns-401-despite-the-valid-token-distributed-for-a-secure-endpoint

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!