C# 具有JWT授权的自定义中间件-IsAuthenticated=False
我编写了一个小型中间件代码(asp.net core v2.2+c#),在执行对服务器的调用后运行,如果用户经过身份验证,则运行一些逻辑。由于是WebAPI,身份验证是通过使用承载令牌完成的 中间件的外观如下所示:C# 具有JWT授权的自定义中间件-IsAuthenticated=False,c#,asp.net,asp.net-core,asp.net-web-api,C#,Asp.net,Asp.net Core,Asp.net Web Api,我编写了一个小型中间件代码(asp.net core v2.2+c#),在执行对服务器的调用后运行,如果用户经过身份验证,则运行一些逻辑。由于是WebAPI,身份验证是通过使用承载令牌完成的 中间件的外观如下所示: public class MyMiddleware { private readonly RequestDelegate _next; public MyMiddleware(RequestDelegate next) { _next = n
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>();
}
}
我还检查了httpContext.Request
对象是否包含Authorization
头,它确实包含
为什么
httpContext.User
对象看起来请求未经授权?下面是一个简单的演示:
1.生成令牌:
[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;
}
}
3.自定义MyMiddleware(与您的相同)
4.授权api:
[HttpGet]
[Authorize]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "High Time1", "High Time2", "High Time3", "High Time4", "High Time5" };
}
[HttpGet]
[授权]
公共行动结果获取()
{
返回新字符串[]{“High Time1”、“High Time2”、“High Time3”、“High Time4”、“High Time5”};
}
5.结果:
以下是一个简单的演示: 1.生成令牌:
[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;
}
}
3.自定义MyMiddleware(与您的相同)
4.授权api:
[HttpGet]
[Authorize]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "High Time1", "High Time2", "High Time3", "High Time4", "High Time5" };
}
[HttpGet]
[授权]
公共行动结果获取()
{
返回新字符串[]{“High Time1”、“High Time2”、“High Time3”、“High Time4”、“High Time5”};
}
5.结果:
试试
服务.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(…)
谢谢你的回答。相同的结果。如果我没记错的话,IsAuthenticated属性检查是否存在“名称”声明(您还可以在JWT设置上更改哪个声明是名称声明。这不是基于身份验证是否成功。啊,不,这不是名称声明,而是身份验证类型:您的中间件在MVC之后注册,因此只有在请求与任何操作不匹配时才会运行,是这样吗?请尝试services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)。AddJwtBearer(…)
谢谢您的回答。相同的结果。如果我没记错的话,IsAuthenticated属性会检查是否存在“name”声明(您还可以在JWT设置上更改哪个声明是名称声明。这不是基于身份验证是否成功。啊,不,这不是名称声明,而是身份验证类型:您的中间件是在MVC之后注册的,因此只有在请求与任何操作不匹配时才会运行,这是有意的吗?