网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Dpz.Core.EnumLibrary;
using Hangfire.Dashboard;
using Microsoft.AspNetCore.Authentication;
using Microsoft.IdentityModel.Tokens;

namespace Dpz.Core.Web.Jobs.Hangfire;

public class HangfireFilter : IDashboardAuthorizationFilter
{
    private readonly IConfiguration _configuration;

    public HangfireFilter(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    
    public bool Authorize(DashboardContext context)
    {
        var httpContext = context.GetHttpContext();
        if (httpContext == null)
            throw new Exception("HttpContext is null");
        var tokenValue = httpContext.Request.Cookies[Program.AuthorizeCookieName];
        if (string.IsNullOrEmpty(tokenValue))
        {
            httpContext.Response.Redirect("/sign.html");
            return false;
        }
        var signKey = _configuration["SignKey"];
        if (string.IsNullOrEmpty(signKey))
            throw new Exception("configuration SignKey is null");
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidIssuer = "jobs-server",
            ValidAudience = "jobs-client",
            ValidateIssuer = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey)),
            ValidateLifetime = true
        };
        var principal =
            new JwtSecurityTokenHandler().ValidateToken(tokenValue, tokenValidationParameters,
                out var securityToken);
        if (principal.Identity?.IsAuthenticated != true ||
            securityToken is not JwtSecurityToken jwtSecurityToken)
        {
            return false;
        }
        var permissions = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == "Permissions");
        if (permissions == null ||
            !Enum.TryParse(permissions.Value, out Permissions value) || !value.HasFlag(Permissions.System))
        {
            return false;
        }

        return true;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码定义了一个名为 HangfireFilter 的类,它实现了 IDashboardAuthorizationFilter 接口,用于对 Hangfire 的仪表板进行授权控制。Hangfire 是一个用于处理后台任务的库,通常用于 ASP.NET 应用程序中。以下是代码的主要功能和工作原理的详细解释:

1. 构造函数

public HangfireFilter(IConfiguration configuration)
{
    _configuration = configuration;
}
  • 构造函数接受一个 IConfiguration 对象,用于读取应用程序的配置设置(例如,密钥等)。

2. 授权方法

public bool Authorize(DashboardContext context)
  • Authorize 方法是实现 IDashboardAuthorizationFilter 接口的核心方法,用于检查用户是否有权访问 Hangfire 仪表板。

3. 获取 HttpContext

var httpContext = context.GetHttpContext();
if (httpContext == null)
    throw new Exception("HttpContext is null");
  • DashboardContext 中获取 HttpContext,如果为 null,则抛出异常。

4. 获取 JWT 令牌

var tokenValue = httpContext.Request.Cookies[Program.AuthorizeCookieName];
if (string.IsNullOrEmpty(tokenValue))
{
    httpContext.Response.Redirect("/sign.html");
    return false;
}
  • 从请求的 Cookies 中获取 JWT 令牌。如果令牌为空,则重定向用户到登录页面(/sign.html)并返回 false,表示未授权。

5. 验证 JWT 令牌

var signKey = _configuration["SignKey"];
if (string.IsNullOrEmpty(signKey))
    throw new Exception("configuration SignKey is null");
  • 从配置中获取签名密钥(SignKey),如果为空,则抛出异常。

6. 设置令牌验证参数

var tokenValidationParameters = new TokenValidationParameters
{
    ValidIssuer = "jobs-server",
    ValidAudience = "jobs-client",
    ValidateIssuer = true,
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey)),
    ValidateLifetime = true
};
  • 创建 TokenValidationParameters 对象,设置有效的发行者、受众、签名密钥等参数,以便在验证 JWT 时使用。

7. 验证令牌并获取用户主体

var principal =
    new JwtSecurityTokenHandler().ValidateToken(tokenValue, tokenValidationParameters,
        out var securityToken);
  • 使用 JwtSecurityTokenHandler 验证 JWT 令牌,并获取用户的主体(ClaimsPrincipal)。

8. 检查身份验证状态

if (principal.Identity?.IsAuthenticated != true ||
    securityToken is not JwtSecurityToken jwtSecurityToken)
{
    return false;
}
  • 检查用户是否经过身份验证以及返回的安全令牌是否为 JwtSecurityToken 类型。如果不满足条件,则返回 false

9. 检查权限

var permissions = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == "Permissions");
if (permissions == null ||
    !Enum.TryParse(permissions.Value, out Permissions value) || !value.HasFlag(Permissions.System))
{
    return false;
}
  • 从 JWT 中提取权限声明,并检查用户是否具有特定的权限(在此示例中,检查是否具有 Permissions.System 权限)。如果没有权限,则返回 false

10. 返回授权结果

return true;
  • 如果所有检查都通过,则返回 true,表示用户被授权访问 Hangfire 仪表板。

总结

该代码的主要功能是通过验证 JWT 令牌来控制对 Hangfire 仪表板的访问。它确保只有经过身份验证并具有特定权限的用户才能访问该仪表板。

loading