在模拟其他用户时请求Kerberos票证时,安全包中没有凭据

问题描述 投票:1回答:1

上下文:在IIS和IIS重写规则之上使用C#构建的自定义反向代理/ API网关,利用OWIN中间件。

目标:我希望代理首先验证传入的请求(这在IIS中很容易配置)。拥有该身份后,OWIN中间件应根据经过身份验证的用户声明某些内容。但是,之后,请求应该发送到后端API,后端API也经过Windows身份验证。

我尝试的解决方案:在进一步发送请求之前,OWIN中间件应该模拟经过身份验证的身份,请求Kerberos票证并将其放入Authorization标头(如Negotiate XXXXX.....)。

这是使用C#标准库的代码:

var identity = (WindowsIdentity) context.Request.User.Identity;
using (var impersonation = identity.Impersonate())
{
    var spn = "HTTP/" + backendHostname; // e.g. HTTP/myapi.mydomain.com
    var tokenProvider = new KerberosSecurityTokenProvider(spn, TokenImpersonationLevel.Impersonation);
    var token = tokenProvider.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
    var ticketBytes = token.GetRequest();
    var ticket = Convert.ToBase64String(ticketBytes);
    context.Request.Headers.Append("Negotiate", ticket);
}

这是我尝试的替代实现,使用NSSPI

var identity = (WindowsIdentity) context.Request.User.Identity;
using (var impersonation = identity.Impersonate())
{
    var clientCredentials = new ClientCurrentCredential(PackageNames.Kerberos);
    var client = new ClientContext(
        clientCredentials,
        "HTTP/" + backendHostname, // e.g. HTTP/myapi.mydomain.com
        ContextAttrib.MutualAuth |
        ContextAttrib.InitIdentify |
        ContextAttrib.Confidentiality |
        ContextAttrib.ReplayDetect |
        ContextAttrib.SequenceDetect |
        ContextAttrib.Connection |
        ContextAttrib.Delegate
    );
    var clientStatus = client.Init(null, out var tokenBytes);
    var token = Convert.ToBase64String(tokenBytes);
    context.Request.Headers.Append("Negotiate", token);
}

两个实现都抛出异常,归结为以下Win32错误:

安全包中没有可用的凭据

重要信息:

  • 代理托管在IIS中,在服务帐户下运行(比方说srv_ApiGateway
  • IIS中的useAppPoolCredentials设置为True(否则IIS将无法使用Kerberos验证初始请求)
  • 服务帐户(srv_ApiGateway)设置为AD到Trust this user for delegation to any service (Kerberos only)的委派
  • 在这两种实现中,删除模拟并只是在服务帐户工作时请求票证(仅供参考)
  • 代理和后端API都有适当的SPN(直接请求使用Kerberos正确验证)。
  • WindowsIdentity.GetCurrent().ImpersonationLevel内的using返回ImpersonationLevel.Impersonation(这应该可能是Delegation

有没有人对可能导致这种情况的原因提出任何建议?如何修复这种双跳反向代理用例?任何帮助表示赞赏:)

c# kerberos impersonation sspi kerberos-delegation
1个回答
1
投票

假冒级别没有设置为Delegation的原因是由于票证无效。出于某种原因,即使域名列入白名单,Google Chrome也不会为该用户请求授权票证(根据these docs)。尝试使用IE然后使用Chrome工作,即使不是真正的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.