零信任架构Skill zero-trust

零信任架构是一种网络安全模型,基于'永不信任,始终验证'的原则,包括ZTNA、微分割、身份优先安全、连续验证和BeyondCorp模式。适用于设计网络安全架构、实施身份访问控制、构建云原生应用等场景。关键词:零信任、ZTNA、微分割、身份优先、连续验证、BeyondCorp。

零信任架构 0 次安装 0 次浏览 更新于 3/11/2026

名称: 零信任 描述: 零信任架构原则,包括ZTNA、微分割、身份优先安全、连续验证和BeyondCorp模式。用于设计网络安全、实施身份访问控制或构建基于零信任原则的云原生应用程序。

零信任架构

概述

零信任是一种安全模型,它假设基于网络位置没有隐式信任。每个访问请求无论来源如何都必须完全认证、授权和加密。

关键词: 零信任、ZTNA、微分割、身份优先、连续验证、BeyondCorp、永不信任始终验证、最小权限、mTLS、服务网格、身份代理

何时使用此技能

  • 设计网络安全架构
  • 实施身份访问控制
  • 设置微分割
  • 配置服务到服务认证
  • 构建BeyondCorp式访问
  • 实施连续验证
  • 设计云原生安全

零信任原则

原则 描述 实现
永不信任,始终验证 基于网络没有隐式信任 认证每个请求
最小权限 最小必要访问 基于角色、时间限制的访问
假设被破坏 为妥协设计 微分割、减少爆炸半径
明确验证 所有信号用于授权 身份、设备、位置、行为
连续验证 不信任过去的认证 会话验证、基于风险的重认证

零信任架构组件

┌─────────────────────────────────────────────────────────────────┐
│                    零信任架构                                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌────────────┐    ┌─────────────┐    ┌──────────────────────┐  │
│  │   用户     │───▶│  身份代理   │───▶│  策略引擎            │  │
│  │   + 设备   │    │             │    │  (上下文分析)        │  │
│  └────────────┘    └─────────────┘    └──────────┬───────────┘  │
│                                                   │              │
│                           ┌───────────────────────┘              │
│                           ▼                                      │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │                   信任信号                                │   │
│  ├──────────────────────────────────────────────────────────┤   │
│  │ • 身份 (MFA, SSO)    • 设备姿态 (MDM, 健康)              │   │
│  │ • 位置 (地理, IP)    • 行为 (异常检测)                    │   │
│  │ • 时间 (工作时间)    • 风险评分 (连续)                    │   │
│  └──────────────────────────────────────────────────────────┘   │
│                           │                                      │
│                           ▼                                      │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │               微分割资源                                 │   │
│  ├──────────────────────────────────────────────────────────┤   │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐     │   │
│  │  │ 应用A   │  │ 应用B   │  │ 数据    │  │ 服务    │     │   │
│  │  │ (mTLS)  │  │ (mTLS)  │  │ (加密)  │  │ (mTLS)  │     │   │
│  │  └─────────┘  └─────────┘  └─────────┘  └─────────┘     │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

身份优先安全

身份代理模式

// 用于零信任访问的身份感知代理
// 所有请求都经过身份验证
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;

public enum AccessDecision { Allow, Deny, Challenge }

/// <summary>
/// 访问决策的上下文。
/// </summary>
public sealed record AccessContext(
    string UserId,
    string? DeviceId,
    DevicePosture DevicePosture,
    LocationInfo Location,
    double RiskScore,
    string RequestedResource,
    string RequestedAction);

/// <summary>
/// 零信任策略决策引擎。
/// </summary>
public sealed class PolicyEngine(IEnumerable<IAccessPolicy> policies)
{
    private static readonly HashSet<string> HighRiskCountries = ["XX", "YY", "ZZ"];
    private static readonly string[] OfficeIpRanges = ["10.0.0.0/8", "192.168.1.0/24"];

    public AccessDecision Evaluate(AccessContext context)
    {
        // 检查设备姿态
        if (!CheckDevicePosture(context))
            return AccessDecision.Deny;

        // 检查位置策略
        if (!CheckLocation(context))
            return AccessDecision.Challenge;

        // 检查风险评分
        if (context.RiskScore > 0.8)
            return AccessDecision.Deny;
        if (context.RiskScore > 0.5)
            return AccessDecision.Challenge;

        // 检查资源特定策略
        foreach (var policy in policies)
        {
            if (policy.Matches(context))
                return policy.Evaluate(context);
        }

        // 默认拒绝
        return AccessDecision.Deny;
    }

    private static bool CheckDevicePosture(AccessContext context)
    {
        var posture = context.DevicePosture;

        if (!posture.IsManaged) return false;
        if (!posture.DiskEncrypted) return false;
        if (!posture.FirewallEnabled) return false;
        if (string.Compare(posture.OsVersion, "min_required_version", StringComparison.Ordinal) < 0)
            return false;

        return true;
    }

    private static bool CheckLocation(AccessContext context)
    {
        if (HighRiskCountries.Contains(context.Location.Country))
            return false;

        if (!IsOfficeIp(context.Location.IpAddress, OfficeIpRanges))
        {
            if (!context.DevicePosture.VpnConnected)
                return false;
        }

        return true;
    }

    private static bool IsOfficeIp(string? ip, string[] ranges) =>
        ip is not null && ranges.Any(r => IpInRange(ip, r));

    private static bool IpInRange(string ip, string cidr) => true; // 简化 - 实现CIDR匹配
}

/// <summary>
/// 零信任中间件 - 验证每个请求。
/// </summary>
public sealed class ZeroTrustMiddleware(
    RequestDelegate next,
    PolicyEngine policyEngine,
    IDevicePostureService deviceService,
    ILocationService locationService,
    IRiskScoreService riskService,
    TokenValidationParameters tokenParams)
{
    public async Task InvokeAsync(HttpContext context)
    {
        var authHeader = context.Request.Headers.Authorization.FirstOrDefault();
        if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer "))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsJsonAsync(new { error = "需要认证" });
            return;
        }

        var token = authHeader["Bearer ".Length..];

        try
        {
            var handler = new JwtSecurityTokenHandler();
            var principal = handler.ValidateToken(token, tokenParams, out _);
            var userId = principal.FindFirst("sub")?.Value ?? throw new SecurityTokenException("缺少sub声明");

            var accessContext = new AccessContext(
                UserId: userId,
                DeviceId: context.Request.Headers["X-Device-ID"].FirstOrDefault(),
                DevicePosture: await deviceService.GetPostureAsync(context.Request),
                Location: await locationService.GetLocationAsync(context.Request),
                RiskScore: await riskService.CalculateAsync(context.Request, principal),
                RequestedResource: context.Request.Path,
                RequestedAction: context.Request.Method);

            var decision = policyEngine.Evaluate(accessContext);

            switch (decision)
            {
                case AccessDecision.Deny:
                    context.Response.StatusCode = 403;
                    await context.Response.WriteAsJsonAsync(new { error = "策略拒绝访问" });
                    return;

                case AccessDecision.Challenge:
                    context.Response.StatusCode = 401;
                    await context.Response.WriteAsJsonAsync(new
                    {
                        error = "需要升级认证",
                        methods = new[] { "mfa", "生物识别" }
                    });
                    return;

                case AccessDecision.Allow:
                    await next(context);
                    break;
            }
        }
        catch (SecurityTokenException)
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsJsonAsync(new { error = "无效令牌" });
        }
    }
}

public interface IAccessPolicy
{
    bool Matches(AccessContext context);
    AccessDecision Evaluate(AccessContext context);
}

设备信任验证

// 零信任的设备姿态验证
using System.Security.Cryptography;
using System.Text;

/// <summary>
/// 设备安全姿态。
/// </summary>
public sealed record DevicePosture
{
    public required string DeviceId { get; init; }
    public required string Platform { get; init; }
    public required string OsVersion { get; init; }
    public required bool IsManaged { get; init; }
    public required bool IsCompliant { get; init; }
    public required bool DiskEncrypted { get; init; }
    public required bool FirewallEnabled { get; init; }
    public required bool AntivirusRunning { get; init; }
    public required bool ScreenLockEnabled { get; init; }
    public required bool VpnConnected { get; init; }
    public required DateTime LastSync { get; init; }
    public required List<string> Certificates { get; init; }
    public required List<string> InstalledAgents { get; init; }
}

/// <summary>
/// 设备验证结果。
/// </summary>
public sealed record DeviceVerificationResult(bool IsTrusted, List<string> Failures);

/// <summary>
/// 注册设备信息。
/// </summary>
public sealed record RegisteredDevice(string DeviceId, string UserId, DateTime RegisteredAt, DevicePosture Posture);

/// <summary>
/// 设备验证策略配置。
/// </summary>
public sealed record DevicePolicy
{
    public bool RequireManaged { get; init; }
    public bool RequireCompliant { get; init; }
    public bool RequireEncryption { get; init; }
    public bool RequireFirewall { get; init; }
    public bool RequireAntivirus { get; init; }
    public bool RequireScreenLock { get; init; }
    public Dictionary<string, string> MinOsVersion { get; init; } = new();
    public int MaxSyncAgeHours { get; init; } = 24;
    public List<string> RequiredAgents { get; init; } = [];
}

/// <summary>
/// 验证设备满足安全要求。
/// </summary>
public sealed class DeviceVerifier(DevicePolicy policy)
{
    private readonly Dictionary<string, RegisteredDevice> _trustedDevices = new();

    public DeviceVerificationResult VerifyDevice(DevicePosture posture)
    {
        var failures = new List<string>();

        // 检查设备是否被管理(MDM注册)
        if (policy.RequireManaged && !posture.IsManaged)
            failures.Add("设备必须由MDM管理");

        // 检查MDM合规性
        if (policy.RequireCompliant && !posture.IsCompliant)
            failures.Add("设备不符合MDM合规要求");

        // 检查磁盘加密
        if (policy.RequireEncryption && !posture.DiskEncrypted)
            failures.Add("需要磁盘加密");

        // 检查防火墙
        if (policy.RequireFirewall && !posture.FirewallEnabled)
            failures.Add("防火墙必须启用");

        // 检查防病毒软件
        if (policy.RequireAntivirus && !posture.AntivirusRunning)
            failures.Add("防病毒软件必须运行");

        // 检查屏幕锁
        if (policy.RequireScreenLock && !posture.ScreenLockEnabled)
            failures.Add("屏幕锁必须启用");

        // 检查操作系统版本
        if (policy.MinOsVersion.TryGetValue(posture.Platform, out var minOs))
        {
            if (string.Compare(posture.OsVersion, minOs, StringComparison.Ordinal) < 0)
                failures.Add($"操作系统版本 {posture.OsVersion} 低于最低要求 {minOs}");
        }

        // 检查最后同步时间
        var ageHours = (DateTime.UtcNow - posture.LastSync).TotalHours;
        if (ageHours > policy.MaxSyncAgeHours)
            failures.Add($"设备姿态数据已过时 {ageHours:F1} 小时");

        // 检查所需代理
        var requiredAgents = policy.RequiredAgents.ToHashSet();
        var installedAgents = posture.InstalledAgents.ToHashSet();
        var missingAgents = requiredAgents.Except(installedAgents).ToList();
        if (missingAgents.Count > 0)
            failures.Add($"缺少所需代理: {string.Join(", ", missingAgents)}");

        return new DeviceVerificationResult(failures.Count == 0, failures);
    }

    public string RegisterDevice(DevicePosture posture, string userId)
    {
        var fingerprint = CalculateFingerprint(posture);
        _trustedDevices[fingerprint] = new RegisteredDevice(
            posture.DeviceId,
            userId,
            DateTime.UtcNow,
            posture);
        return fingerprint;
    }

    private static string CalculateFingerprint(DevicePosture posture)
    {
        var sortedCerts = string.Join(",", posture.Certificates.OrderBy(c => c));
        var content = $"{posture.DeviceId}|{posture.Platform}|{sortedCerts}";
        var hash = SHA256.HashData(Encoding.UTF8.GetBytes(content));
        return Convert.ToHexString(hash)[..32].ToLowerInvariant();
    }
}

微分割

使用服务网格的网络微分割

# 用于微分割的Istio授权策略
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: frontend-to-api
  namespace: production
spec:
  selector:
    matchLabels:
      app: api
  action: ALLOW
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/frontend"]
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/v1/*"]
      when:
        - key: request.headers[x-request-id]
          notValues: [""]
---
# 拒绝所有其他到API的流量
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: api-deny-all
  namespace: production
spec:
  selector:
    matchLabels:
      app: api
  action: DENY
  rules:
    - from:
        - source:
            notPrincipals: ["cluster.local/ns/production/sa/frontend"]

mTLS配置

# Istio PeerAuthentication - 要求mTLS
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT
---
# Istio DestinationRule - 强制到上游的mTLS
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: api-mtls
  namespace: production
spec:
  host: api.production.svc.cluster.local
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

连续验证

基于风险的认证

// 连续基于风险的认证
// 在整个会话中重新评估信任
using System.Collections.Concurrent;
using System.Security.Cryptography;

/// <summary>
/// 会话风险评估结果。
/// </summary>
public sealed record SessionRisk(
    string SessionId,
    string UserId,
    double CurrentRiskScore,
    Dictionary<string, double> Factors,
    DateTime LastAssessment,
    bool StepUpRequired,
    DateTime? StepUpCompleted);

/// <summary>
/// 风险评估上下文。
/// </summary>
public sealed record RiskContext
{
    public required string UserId { get; init; }
    public DateTime? LastMfaTime { get; init; }
    public LocationInfo? Location { get; init; }
    public string? DeviceFingerprint { get; init; }
    public List<RequestInfo> RecentRequests { get; init; } = [];
    public bool AccessingSensitiveResource { get; init; }
}

public sealed record RequestInfo(string Endpoint, bool Unusual);

/// <summary>
/// 连续验证会话信任。
/// </summary>
public sealed class ContinuousVerificationService
{
    private readonly ConcurrentDictionary<string, SessionRisk> _sessions = new();
    private readonly double _riskThreshold = 0.7;
    private readonly double _stepUpThreshold = 0.5;

    public async Task<SessionRisk> AssessRiskAsync(string sessionId, RiskContext context, CancellationToken ct = default)
    {
        var factors = new Dictionary<string, double>();
        var riskScore = 0.0;

        // 因素1: 距离上次MFA的时间 (0.0 - 0.2)
        if (context.LastMfaTime.HasValue)
        {
            var hoursSinceMfa = (DateTime.UtcNow - context.LastMfaTime.Value).TotalHours;
            if (hoursSinceMfa > 8)
            {
                factors["mfa_age"] = Math.Min(0.2, hoursSinceMfa * 0.01);
                riskScore += factors["mfa_age"];
            }
        }

        // 因素2: 位置变化 (0.0 - 0.25)
        if (DetectLocationChange(sessionId, context))
        {
            factors["location_change"] = 0.25;
            riskScore += 0.25;
        }

        // 因素3: 设备变化 (0.0 - 0.3)
        if (DetectDeviceChange(sessionId, context))
        {
            factors["device_change"] = 0.3;
            riskScore += 0.3;
        }

        // 因素4: 异常行为 (0.0 - 0.15)
        var behaviorScore = AnalyzeBehavior(context);
        factors["behavior"] = behaviorScore;
        riskScore += behaviorScore;

        // 因素5: 敏感资源访问 (0.0 - 0.1)
        if (context.AccessingSensitiveResource)
        {
            factors["sensitive_access"] = 0.1;
            riskScore += 0.1;
        }

        var sessionRisk = new SessionRisk(
            SessionId: sessionId,
            UserId: context.UserId,
            CurrentRiskScore: Math.Min(1.0, riskScore),
            Factors: factors,
            LastAssessment: DateTime.UtcNow,
            StepUpRequired: riskScore > _stepUpThreshold,
            StepUpCompleted: null);

        _sessions[sessionId] = sessionRisk;
        return sessionRisk;
    }

    private bool DetectLocationChange(string sessionId, RiskContext context)
    {
        if (!_sessions.TryGetValue(sessionId, out var prevSession))
            return false;

        // 检查不可能旅行
        return IsImpossibleTravel(prevSession, context.Location);
    }

    private bool DetectDeviceChange(string sessionId, RiskContext context)
    {
        if (!_sessions.TryGetValue(sessionId, out var prevSession))
            return false;

        // 比较设备指纹
        return context.DeviceFingerprint != null &&
               prevSession.Factors.ContainsKey("initial_device");
    }

    private static double AnalyzeBehavior(RiskContext context)
    {
        var anomalyScore = 0.0;

        // 高请求率
        if (context.RecentRequests.Count > 100)
            anomalyScore += 0.05;

        // 异常端点
        var unusualCount = context.RecentRequests.Count(r => r.Unusual);
        if (unusualCount > 0)
            anomalyScore += unusualCount * 0.02;

        // 非工作时间访问
        var hour = DateTime.UtcNow.Hour;
        if (hour < 6 || hour > 22)
            anomalyScore += 0.03;

        return Math.Min(0.15, anomalyScore);
    }

    private static bool IsImpossibleTravel(SessionRisk session, LocationInfo? currentLocation) => false; // 实现
}

/// <summary>
/// 升级认证挑战。
/// </summary>
public sealed record StepUpChallenge(string ChallengeId, List<string> RequiredMethods, int ExpiresInSeconds, string UserId);

/// <summary>
/// 处理升级认证挑战。
/// </summary>
public sealed class StepUpAuthenticationService
{
    public StepUpChallenge CreateChallenge(string userId, Dictionary<string, double> riskFactors)
    {
        var requiredMethods = new List<string>();

        if (riskFactors.ContainsKey("device_change"))
        {
            requiredMethods.Add("push_notification");
            requiredMethods.Add("email_verification");
        }

        if (riskFactors.ContainsKey("location_change"))
            requiredMethods.Add("sms_code");

        if (riskFactors.ContainsKey("sensitive_access"))
            requiredMethods.Add("biometric");

        // 如果没有特定要求,默认使用TOTP
        if (requiredMethods.Count == 0)
            requiredMethods.Add("totp");

        return new StepUpChallenge(
            ChallengeId: GenerateChallengeId(),
            RequiredMethods: requiredMethods,
            ExpiresInSeconds: 300,
            UserId: userId);
    }

    public Task<bool> VerifyAsync(string challengeId, Dictionary<string, string> response, CancellationToken ct = default)
    {
        // 实现取决于认证方法
        return Task.FromResult(true);
    }

    private static string GenerateChallengeId() =>
        Convert.ToHexString(RandomNumberGenerator.GetBytes(16)).ToLowerInvariant();
}

BeyondCorp实现

应用级访问代理

/// <summary>
/// BeyondCorp式访问代理。
/// 无需VPN - 所有访问通过身份感知代理。
/// </summary>
public sealed record BeyondCorpConfig(
    string IdentityProvider,
    string ClientId,
    List<IAccessPolicy> AccessPolicies);

public sealed record ProxySession(
    string Id,
    UserInfo User,
    DateTimeOffset ExpiresAt)
{
    public bool IsExpired => DateTimeOffset.UtcNow >= ExpiresAt;
}

public sealed record UserInfo(string Email, List<string> Groups);
public sealed record TargetApplication(string Name, string BackendUrl);

public sealed class BeyondCorpProxyMiddleware(
    RequestDelegate next,
    BeyondCorpConfig config,
    ISessionValidator sessionValidator,
    IDeviceVerifier deviceVerifier,
    IHttpClientFactory httpClientFactory)
{
    private const string SessionCookieName = "_beyondcorp_session";

    public async Task InvokeAsync(HttpContext context)
    {
        // 步骤1: 检查有效会话
        var session = await GetSessionAsync(context);
        if (session is null)
        {
            RedirectToLogin(context);
            return;
        }

        // 步骤2: 验证设备信任
        var deviceTrust = await VerifyDeviceAsync(context, session);
        if (!deviceTrust.IsTrusted)
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            await context.Response.WriteAsJsonAsync(new { error = "设备不可信", reason = deviceTrust.Reason });
            return;
        }

        // 步骤3: 检查访问策略
        var target = GetTargetApplication(context);
        var accessDecision = await CheckAccessPolicyAsync(session.User, deviceTrust, target, context);
        if (!accessDecision.Allowed)
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            await context.Response.WriteAsJsonAsync(new { error = accessDecision.Reason });
            return;
        }

        // 步骤4: 代理请求到后端
        await ProxyRequestAsync(context, session, target);
    }

    private async Task<ProxySession?> GetSessionAsync(HttpContext context)
    {
        if (!context.Request.Cookies.TryGetValue(SessionCookieName, out var sessionCookie))
            return null;

        var session = await sessionValidator.ValidateAsync(sessionCookie);
        return session is null || session.IsExpired ? null : session;
    }

    private void RedirectToLogin(HttpContext context)
    {
        var parameters = new Dictionary<string, string?>
        {
            ["client_id"] = config.ClientId,
            ["redirect_uri"] = context.Request.GetDisplayUrl(),
            ["response_type"] = "code",
            ["scope"] = "openid profile email",
            ["state"] = GenerateState()
        };

        var queryString = QueryString.Create(parameters);
        var authUrl = $"{config.IdentityProvider}/authorize{queryString}";
        context.Response.Redirect(authUrl);
    }

    private async Task<DeviceTrust> VerifyDeviceAsync(HttpContext context, ProxySession session)
    {
        var clientCert = context.Request.Headers["X-Client-Cert"].FirstOrDefault();
        var deviceId = context.Request.Headers["X-Device-ID"].FirstOrDefault();

        return await deviceVerifier.VerifyAsync(deviceId, clientCert);
    }

    private TargetApplication GetTargetApplication(HttpContext context)
    {
        // 基于主机头或路径路由到后端
        var host = context.Request.Host.Value;
        return new TargetApplication(host, $"https://backend-{host}");
    }

    private async Task<AccessDecision> CheckAccessPolicyAsync(
        UserInfo user, DeviceTrust device, TargetApplication target, HttpContext context)
    {
        var policyContext = new AccessPolicyContext(
            User: user,
            Groups: user.Groups,
            Device: device,
            Target: target,
            Timestamp: DateTimeOffset.UtcNow,
            SourceIp: context.Connection.RemoteIpAddress?.ToString() ?? "unknown",
            RequestPath: context.Request.Path.Value ?? "/",
            RequestMethod: context.Request.Method);

        foreach (var policy in config.AccessPolicies)
        {
            if (policy.Matches(policyContext))
                return policy.Evaluate(policyContext);
        }

        // 默认拒绝
        return new AccessDecision(Allowed: false, Reason: "无匹配策略");
    }

    private async Task ProxyRequestAsync(HttpContext context, ProxySession session, TargetApplication target)
    {
        var client = httpClientFactory.CreateClient("BeyondCorpProxy");
        var requestMessage = new HttpRequestMessage
        {
            Method = new HttpMethod(context.Request.Method),
            RequestUri = new Uri($"{target.BackendUrl}{context.Request.Path}{context.Request.QueryString}")
        };

        // 复制头(排除hop-by-hop)
        string[] hopByHopHeaders = ["host", "connection", "keep-alive", "transfer-encoding"];
        foreach (var header in context.Request.Headers)
        {
            if (!hopByHopHeaders.Contains(header.Key, StringComparer.OrdinalIgnoreCase))
                requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
        }

        // 添加身份头
        requestMessage.Headers.Add("X-Forwarded-User", session.User.Email);
        requestMessage.Headers.Add("X-Forwarded-Groups", string.Join(",", session.User.Groups));
        requestMessage.Headers.Add("X-Request-Id", Guid.NewGuid().ToString("N"));

        // 如果存在,复制体
        if (context.Request.ContentLength > 0)
            requestMessage.Content = new StreamContent(context.Request.Body);

        var response = await client.SendAsync(requestMessage);
        context.Response.StatusCode = (int)response.StatusCode;
        await response.Content.CopyToAsync(context.Response.Body);
    }

    private static string GenerateState() =>
        Convert.ToBase64String(RandomNumberGenerator.GetBytes(32));
}

public sealed record AccessPolicyContext(
    UserInfo User,
    List<string> Groups,
    DeviceTrust Device,
    TargetApplication Target,
    DateTimeOffset Timestamp,
    string SourceIp,
    string RequestPath,
    string RequestMethod);

public interface IAccessPolicy
{
    bool Matches(AccessPolicyContext context);
    AccessDecision Evaluate(AccessPolicyContext context);
}

public interface ISessionValidator
{
    Task<ProxySession?> ValidateAsync(string sessionCookie, CancellationToken ct = default);
}

快速决策树

您正在实现什么?

  1. 为零信任重新设计网络 -> 从微分割 + 身份代理开始
  2. 服务到服务认证 -> 使用服务网格实现mTLS
  3. 用户访问应用程序 -> BeyondCorp式访问代理
  4. 设备信任验证 -> MDM集成 + 设备姿态检查
  5. 连续会话安全 -> 基于风险的认证 + 升级认证
  6. API安全 -> 令牌验证 + 上下文感知策略

零信任检查表

身份和访问

  • [ ] 所有用户通过强MFA认证
  • [ ] 设备身份验证(证书/MDM)
  • [ ] 即时访问配置
  • [ ] 最小权限访问模型
  • [ ] 会话超时和重新认证
  • [ ] 特权访问管理(PAM)

网络和工作负载

  • [ ] 内部网络没有隐式信任
  • [ ] 实现微分割
  • [ ] 所有服务通信使用mTLS
  • [ ] 网络策略默认拒绝
  • [ ] 东西向流量加密
  • [ ] 出站流量控制

数据保护

  • [ ] 数据在静止和传输中加密
  • [ ] 数据分类和标记
  • [ ] 执行DLP策略
  • [ ] 访问日志和审计
  • [ ] 识别敏感数据

监控和分析

  • [ ] 记录所有访问尝试
  • [ ] 行为分析活跃
  • [ ] 配置异常检测
  • [ ] SIEM集成
  • [ ] 自动化响应预案

参考

  • 零信任架构: 参见 references/zero-trust-architecture.md 获取详细模式
  • ZTNA实现: 参见 references/ztna-implementation.md 获取网络访问

最后更新: 2025-12-26