问题
I wrote a small middleware code (asp.net core v2.2 + c#) that run AFTER a call to server is executed and run some logic if the user is authenticated. Since it's WebAPI - the authentication is done by using Bearer token.
This how the middleware looks like:
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
await _next(httpContext).ConfigureAwait(false); // calling next middleware
if (httpContext.User.Identity.IsAuthenticated) // <==================== Allways false
{
// Do my logics
}
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class MyMiddlewareExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyMiddleware>();
}
}
The problem is that the expression httpContext.User.Identity.IsAuthenticated
allways return false
, even if the request successfully authenticated with the service.
My Startup.cs
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ...
app.UseAuthentication();
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
// Formatting numbers, dates, etc.
SupportedCultures = new[] { new CultureInfo("en-US") },
// UI strings that we have localized.
SupportedUICultures = supportedCultures,
});
app.UseMvc();
app.UseMyMiddleware(ConfigurationManager.ApplicationName);
}
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAuthentication().AddJwtBearer(options =>
{
// ...
});
}
I also checked that the httpContext.Request
object contain the Authorization
header and it does.
Why the httpContext.User
object seems like the request is unauthorized?
回答1:
Here is a simple demo like below:
1.Generate the token:
[Route("api/[controller]")]
[ApiController]
public class LoginController : Controller
{
private IConfiguration _config;
public LoginController(IConfiguration config)
{
_config = config;
}
[AllowAnonymous]
[HttpPost]
public IActionResult Login([FromBody]UserModel login)
{
IActionResult response = Unauthorized();
var user = AuthenticateUser(login);
if (user != null)
{
var tokenString = GenerateJSONWebToken(user);
response = Ok(new { token = tokenString });
}
return response;
}
private string GenerateJSONWebToken(UserModel userInfo)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim>{
new Claim(JwtRegisteredClaimNames.Sub, userInfo.Username),
new Claim(JwtRegisteredClaimNames.Email, userInfo.EmailAddress),
new Claim("DateOfJoing", userInfo.DateOfJoing.ToString("yyyy-MM-dd")),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
_config["Jwt:Issuer"],
claims: claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
private UserModel AuthenticateUser(UserModel login)
{
UserModel user = null;
//Validate the User Credentials
//Demo Purpose, I have Passed HardCoded User Information
if (login.Username == "Jignesh")
{
user = new UserModel { Username = "Jignesh Trivedi", EmailAddress = "test.btest@gmail.com" };
}
return user;
}
}
2.Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
app.UseMyMiddleware();
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseMvc();
}
3.custom MyMiddleware(the same as yours)
4.Authorize api:
[HttpGet]
[Authorize]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "High Time1", "High Time2", "High Time3", "High Time4", "High Time5" };
}
5.Result:
来源:https://stackoverflow.com/questions/58154183/custom-middleware-with-jwt-authorization-isauthenticated-false