You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.7 KiB
C#
83 lines
2.7 KiB
C#
using System;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Options;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Haoliang.Core.Services;
|
|
using Haoliang.Models.Common;
|
|
|
|
namespace Haoliang.Api.Middleware
|
|
{
|
|
public class JwtMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly IAuthService _authService;
|
|
private readonly JwtSettings _jwtSettings;
|
|
|
|
public JwtMiddleware(RequestDelegate next, IAuthService authService, IOptions<JwtSettings> jwtSettings)
|
|
{
|
|
_next = next;
|
|
_authService = authService;
|
|
_jwtSettings = jwtSettings.Value;
|
|
}
|
|
|
|
public async Task Invoke(HttpContext context)
|
|
{
|
|
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
|
|
|
|
if (token != null)
|
|
await AttachUserToContext(context, token);
|
|
|
|
await _next(context);
|
|
}
|
|
|
|
private async Task AttachUserToContext(HttpContext context, string token)
|
|
{
|
|
try
|
|
{
|
|
var tokenHandler = new JwtSecurityTokenHandler();
|
|
var key = Encoding.ASCII.GetBytes(_jwtSettings.Secret);
|
|
|
|
tokenHandler.ValidateToken(token, new TokenValidationParameters
|
|
{
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKey = new SymmetricSecurityKey(key),
|
|
ValidateIssuer = false,
|
|
ValidateAudience = false,
|
|
ClockSkew = TimeSpan.Zero
|
|
}, out SecurityToken validatedToken);
|
|
|
|
var jwtToken = (JwtSecurityToken)validatedToken;
|
|
var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);
|
|
|
|
// Attach user to context on successful jwt validation
|
|
context.Items["User"] = await _authService.GetUserByIdAsync(userId);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Token is not valid
|
|
// Log the error but don't throw, allow the request to continue
|
|
// The authorization filter will handle the authentication failure
|
|
}
|
|
}
|
|
}
|
|
|
|
public class JwtSettings
|
|
{
|
|
public string Secret { get; set; }
|
|
public string Issuer { get; set; }
|
|
public string Audience { get; set; }
|
|
public int ExpirationMinutes { get; set; } = 60;
|
|
}
|
|
|
|
public static class JwtMiddlewareExtensions
|
|
{
|
|
public static IApplicationBuilder UseJwtMiddleware(this IApplicationBuilder builder)
|
|
{
|
|
return builder.UseMiddleware<JwtMiddleware>();
|
|
}
|
|
}
|
|
} |