将Kerberos与委派一起使用时,GSS API和SSPI API有什么区别?

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

[将Kerberos与委派一起使用时,GSS API和SSPI API有什么区别?

我有一个在Tomcat服务器中运行Java代码的中间件。中间件使用Kerberos(GSS API)对用户进行身份验证。如果授权标头中没有Kerberos令牌,则中间件将返回401并附加WWW-Authenticate:Negotiate响应标头以初始化SPNEGO身份验证。

使用GSSContext.acceptSecContext检查传入的服务票证工作正常。

但是,在委托案中我有一些问题。

正如名称“ middleware”所示,我的java服务必须使用具有原始用户主体的Kerberos身份验证来调用后端服务。为此,我实现了Kerberos Java GSS API委托机制。同样,AD配置正确,并且tomcat作为具有特定服务帐户的服务运行。

为了测试该实现,我编写了一个Java测试客户端,该客户端使用GSS API来获取中间件的凭单。使用管理员权限运行Java测试客户端或使用kinit -f获取可转发票证,客户端和中间件组合可以正常工作:客户端获取票证,中间件接受票证,GSSContext.getCredDelegState()返回true,使用GSSContext.getDelegCred(),中间件获取委托凭证,后端的登录正常。

此外,我还使用浏览器和小型C#测试客户端测试了中间件实现。两者都使用SPNEGO。在这种情况下,授权也有效。我收到验证成功的消息,并获得用户Principal。使用浏览器或C#测试客户端,我在中间件中得到以下调试打印:

    Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator false KeyTab is D:/app/Tomcat_9019_SSO/conf/tomcat.keytab refreshKrb5Config is true principal is HTTP/[email protected] tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
Java config name: C:\Windows\kerb5.ini
Loading krb5 profile at C:\Windows\kerb5.ini
Loaded from Java config
>>> KdcAccessibility: reset
principal is HTTP/[email protected]
Will use keytab
Commit Succeeded

2020-03-18 06:36:50.254  INFO .e.s.a.t.a.KerberosCheckAuthTicketAction [TC~3~c80e3d5b-3] : Starting check of incoming Kerberos service ticket.
Search Subject for SPNEGO ACCEPT cred (<<DEF>>, sun.security.jgss.spnego.SpNegoCredElement)
Search Subject for Kerberos V5 ACCEPT cred (<<DEF>>, sun.security.jgss.krb5.Krb5AcceptCredential)
Found KeyTab D:\app\Tomcat_9019_SSO\conf\tomcat.keytab for HTTP/[email protected]
Found KeyTab D:\app\Tomcat_9019_SSO\conf\tomcat.keytab for HTTP/[email protected]
Search Subject for Kerberos V5 ACCEPT cred (<<DEF>>, sun.security.jgss.krb5.Krb5AcceptCredential)
Found KeyTab D:\app\Tomcat_9019_SSO\conf\tomcat.keytab for HTTP/[email protected]
Found KeyTab D:\app\Tomcat_9019_SSO\conf\tomcat.keytab for HTTP/[email protected]
Entered Krb5Context.acceptSecContext with state=STATE_NEW
Looking for keys for: HTTP/[email protected]
Added key: 23version: 0
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
Using builtin default etypes for permitted_enctypes
default etypes for permitted_enctypes: 18 17 20 19 16 23.
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
MemoryCache: add 1584509810/000627/5EBDF35F49476E365F32DE53C3CAFA81C4730A13D881ECA15E9F43023F99A80B/[email protected] to [email protected]|HTTP/[email protected]
>>> KrbApReq: authenticate succeed.
Krb5Context setting peerSeqNumber to: 947381056
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
Krb5Context setting mySeqNumber to: 214468704
>>> Constrained deleg from GSSCaller{UNKNOWN}
Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator true KeyTab is D:/app/Tomcat_9019_SSO/conf/tomcat.keytab refreshKrb5Config is false principal is HTTP/[email protected] tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Looking for keys for: HTTP/[email protected]
Added key: 23version: 0
Looking for keys for: HTTP/[email protected]
Added key: 23version: 0
default etypes for default_tkt_enctypes: 23 18 17.
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=kb01.mydomain.net UDP:88, timeout=30000, number of retries =3, #bytes=174
>>> KDCCommunication: kdc=kb01.mydomain.net UDP:88, timeout=30000,Attempt =1, #bytes=174
>>> KrbKdcReq send: #bytes read=175
>>>Pre-Authentication Data:
         PA-DATA type = 11
         PA-ETYPE-INFO etype = 23, salt =

>>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

>>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
         PA-DATA type = 16

>>>Pre-Authentication Data:
         PA-DATA type = 15

>>> KdcAccessibility: remove kb01.mydomain.net
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
         sTime is Wed Mar 18 06:36:50 CET 2020 1584509810000
         suSec is 765149
         error code is 25
         error Message is Additional pre-authentication required
         sname is krbtgt/[email protected]
         eData provided.
         msgType is 30
>>>Pre-Authentication Data:
         PA-DATA type = 11
         PA-ETYPE-INFO etype = 23, salt =

>>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

>>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
         PA-DATA type = 16

>>>Pre-Authentication Data:
         PA-DATA type = 15

KrbAsReqBuilder: PREAUTH FAILED/REQ, re-send AS-REQ
default etypes for default_tkt_enctypes: 23 18 17.
Looking for keys for: HTTP/[email protected]
Added key: 23version: 0
Looking for keys for: HTTP/[email protected]
Added key: 23version: 0
default etypes for default_tkt_enctypes: 23 18 17.
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=kb01.mydomain.net UDP:88, timeout=30000, number of retries =3, #bytes=253
>>> KDCCommunication: kdc=kb01.mydomain.net UDP:88, timeout=30000,Attempt =1, #bytes=253
>>> KrbKdcReq send: #bytes read=90
>>> KrbKdcReq send: kdc=kb01.mydomain.net TCP:88, timeout=30000, number of retries =3, #bytes=253
>>> KDCCommunication: kdc=kb01.mydomain.net TCP:88, timeout=30000,Attempt =1, #bytes=253
>>>DEBUG: TCPClient reading 2154 bytes
>>> KrbKdcReq send: #bytes read=2154
>>> KdcAccessibility: remove kb01.mydomain.net
Looking for keys for: HTTP/[email protected]
Added key: 23version: 0
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
                [Krb5LoginModule] authentication failed
Message stream modified (41)

使用Java客户端,我在中间件中得到了此调试打印信息:

Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator false KeyTab is D:/app/Tomcat_9019_SSO/conf/tomcat.keytab refreshKrb5Config is true principal is HTTP/[email protected] tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
Java config name: C:\Windows\kerb5.ini
Loading krb5 profile at C:\Windows\kerb5.ini
Loaded from Java config
>>> KdcAccessibility: reset
principal is HTTP/[email protected]
Will use keytab
Commit Succeeded

2020-03-18 06:47:41.029  INFO .e.s.a.t.a.KerberosCheckAuthTicketAction [TC~9~c80e3d5b-9] : Starting check of incoming Kerberos service ticket.
Search Subject for SPNEGO ACCEPT cred (<<DEF>>, sun.security.jgss.spnego.SpNegoCredElement)
Search Subject for Kerberos V5 ACCEPT cred (<<DEF>>, sun.security.jgss.krb5.Krb5AcceptCredential)
Found KeyTab D:\app\Tomcat_9019_SSO\conf\tomcat.keytab for HTTP/[email protected]
Found KeyTab D:\app\Tomcat_9019_SSO\conf\tomcat.keytab for HTTP/[email protected]
Search Subject for Kerberos V5 ACCEPT cred (<<DEF>>, sun.security.jgss.krb5.Krb5AcceptCredential)
Found KeyTab D:\app\Tomcat_9019_SSO\conf\tomcat.keytab for HTTP/[email protected]
Found KeyTab D:\app\Tomcat_9019_SSO\conf\tomcat.keytab for HTTP/[email protected]
Entered Krb5Context.acceptSecContext with state=STATE_NEW
Looking for keys for: HTTP/[email protected]
Added key: 23version: 0
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
Using builtin default etypes for permitted_enctypes
default etypes for permitted_enctypes: 18 17 20 19 16 23.
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
MemoryCache: add 1584510459/567826/FDE0027391B8BF26BF807FF04E5FD5F7CE38794A3264EB298BB36F736B2CF050/[email protected] to [email protected]|HTTP/[email protected]
>>> KrbApReq: authenticate succeed.
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
>>>Delegated Creds have [email protected] sname=krbtgt/[email protected] authtime=20200318054735Z starttime=20200318054739Z endtime=20200318154735ZrenewTill=null
Krb5Context setting peerSeqNumber to: 99984043
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
Krb5Context setting mySeqNumber to: 161819208

但是,这里的主要问题是,在Java客户端的情况下,委托有效,在浏览器和C#客户端的情况下,委托无效。注意,已将浏览器配置为将域列入授权白名单。

其他信息:我配置了约束委派。带有中间件的Tomcat作为带有AD服务帐户的服务在Windows 2016服务器上运行。

我比较了已发送到中间件的服务票证:

Java(可转发),委托工作:10980字节

C#(授权不起作用):8572字节

浏览器(授权无效):8572字节

为了进行比较,我使用了不带-f选项的kinit来获取不可转发的tgt并测量了大小:

Java(不可转发,委托无效):8174字节

顺便说一句,这会产生相同的错误。

java c# kerberos sspi gss
1个回答
0
投票

您如何在AD中为中间件服务帐户配置委派?不受约束还是受约束?

尝试获取由Java和C#客户端发送的票证的副本,并比较票证的大小。它们应该大致相同,但是如果一个大得多,则该大个包含委托的TGT。

基于日志,看起来Java客户端正在发送不受限制的票证(已委派的TGT,AKA已转发,并且正使用该票证。

我们看不到C#票证所包含的内容,但是中间件在收到后立即尝试与KDC联系,这似乎表明它可能正试图将其交换为委托的票证,但是失败了,因为中间件无法获得它。首先拥有机票。不过,这有点大胆的猜测,因为日志没有以某种方式表明启动AS-REQ的原因。

您可能考虑在中间件和KDC之间获得网络跟踪,以查看在C#情况下它正在发送什么。

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