using System.Collections.Generic;
using Dpz.Core.Entity.Base.PublicStruct;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;

namespace Dpz.Core.Infrastructure.Intercept;

public class InterceptRuleService(IConfiguration configuration) : IInterceptRuleService
{
    public InterceptRule? CheckInterceptRules(HttpContext httpContext)
    {
        var interceptRules =
            configuration.GetSection("InterceptRules").Get<List<InterceptRule>>() ?? [];

        return interceptRules.Find(rule => IsRuleMatched(httpContext, rule));
    }

    private static bool IsRuleMatched(HttpContext httpContext, InterceptRule rule)
    {
        return rule.Type switch
        {
            InterceptType.Uri => CheckUriMatch(httpContext, rule.Pattern),
            InterceptType.RequestMethod => CheckRequestMethodMatch(httpContext, rule.Pattern),
            InterceptType.ClientIp => CheckClientIpMatch(httpContext, rule.Pattern),
            InterceptType.UserAgent => CheckUserAgentMatch(httpContext, rule.Pattern),
            InterceptType.QueryParameter => CheckQueryParameterMatch(
                httpContext,
                rule.Key,
                rule.Pattern
            ),
            InterceptType.Header => CheckHeaderMatch(httpContext, rule.Key, rule.Pattern),
            _ => false,
        };
    }

    private static bool CheckUserAgentMatch(HttpContext httpContext, string pattern)
    {
        var userAgent = httpContext.Request.Headers.UserAgent.ToString();
        return IsPatternMatched(userAgent, pattern);
    }

    private static bool CheckQueryParameterMatch(
        HttpContext httpContext,
        string? key,
        string pattern
    )
    {
        if (string.IsNullOrEmpty(key))
        {
            return false;
        }

        if (!httpContext.Request.Query.TryGetValue(key, out var queryValue))
        {
            return false;
        }

        return IsPatternMatched(queryValue.ToString(), pattern);
    }

    private static bool CheckClientIpMatch(HttpContext httpContext, string pattern)
    {
        var ipAddress = httpContext.Request.GetIpAddress();
        return IsPatternMatched(ipAddress, pattern);
    }

    private static bool CheckUriMatch(HttpContext httpContext, string pattern)
    {
        var requestPath = httpContext.Request.Path.Value ?? "";
        return IsPatternMatched(requestPath, pattern);
    }

    private static bool CheckRequestMethodMatch(HttpContext httpContext, string pattern)
    {
        var requestMethod = httpContext.Request.Method;
        return IsPatternMatched(requestMethod, pattern);
    }

    private static bool CheckHeaderMatch(HttpContext httpContext, string? key, string pattern)
    {
        if (string.IsNullOrEmpty(key))
        {
            return false;
        }

        if (!httpContext.Request.Headers.TryGetValue(key, out var headerValue))
        {
            return false;
        }

        return IsPatternMatched(headerValue.ToString(), pattern);
    }

    private static bool IsPatternMatched(string input, string pattern)
    {
        if (string.IsNullOrEmpty(input) && string.IsNullOrEmpty(pattern))
        {
            return true;
        }

        if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(pattern))
        {
            return false;
        }

        return ApplicationTools.WildcardMatch(input, pattern, ignoreCase: true);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

InterceptRuleService 代码解析

这段代码实现了一个拦截规则服务,用于检查HTTP请求是否符合配置的拦截规则。以下是详细的功能解析:

主要功能

  1. 拦截规则检查:检查传入的HTTP请求是否符合配置文件中定义的任何拦截规则。
  2. 多种匹配类型:支持多种匹配类型,包括URI、请求方法、客户端IP、用户代理、查询参数和请求头。

核心组件

1. 构造函数

public InterceptRuleService(IConfiguration configuration)
  • 接收一个IConfiguration实例,用于从配置文件中读取拦截规则。

2. 主要方法 CheckInterceptRules

public InterceptRule? CheckInterceptRules(HttpContext httpContext)
  • 检查HTTP请求是否匹配任何配置的拦截规则
  • 返回第一个匹配的规则,如果没有匹配则返回null
  • 从配置的"InterceptRules"部分读取规则列表

3. 规则匹配方法 IsRuleMatched

private static bool IsRuleMatched(HttpContext httpContext, InterceptRule rule)
  • 根据规则类型调用相应的匹配检查方法
  • 支持的拦截类型(InterceptType)包括:
    • Uri:检查请求路径
    • RequestMethod:检查HTTP方法
    • ClientIp:检查客户端IP地址
    • UserAgent:检查用户代理字符串
    • QueryParameter:检查查询字符串参数
    • Header:检查请求头

4. 具体匹配检查方法

  • CheckUriMatch:检查请求路径是否匹配模式
  • CheckRequestMethodMatch:检查HTTP方法是否匹配模式
  • CheckClientIpMatch:检查客户端IP是否匹配模式
  • CheckUserAgentMatch:检查User-Agent头是否匹配模式
  • CheckQueryParameterMatch:检查特定查询参数是否匹配模式
  • CheckHeaderMatch:检查特定请求头是否匹配模式

5. 模式匹配方法 IsPatternMatched

private static bool IsPatternMatched(string input, string pattern)
  • 使用ApplicationTools.WildcardMatch进行通配符匹配
  • 支持忽略大小写的匹配
  • 处理空输入和空模式的特殊情况

使用场景

这个服务可以用于:

  • 请求过滤/拦截
  • 访问控制
  • 请求路由
  • 安全防护(如阻止特定IP或User-Agent)
  • API网关功能实现

配置示例

配置文件中可能包含类似这样的拦截规则:

"InterceptRules": [
  {
    "Type": "Uri",
    "Pattern": "/admin/*",
    "Action": "Deny"
  },
  {
    "Type": "ClientIp",
    "Pattern": "192.168.1.*",
    "Action": "Allow"
  }
]

这个服务提供了一种灵活的方式来定义和检查各种HTTP请求拦截规则。

评论加载中...