【问题标题】:Confusion about Java App auth in AD based on Kerberos MSLSA ticket cache基于 Kerberos MSLSA 票证缓存的 AD 中 Java App auth 的困惑
【发布时间】:2021-05-19 11:58:23
【问题描述】:

任务是使用来自 MSLSA 的 Kerberos 票证缓存无密码提示无 keytab,让 myapp 在 AD 中进行身份验证。现在我可以得到 TGT 缓存——它是 FORWARDABLE 和 PROXIABLE——但是我在 LoginContext.login 方法中得到了这个异常。

Debug is  true storeKey true useTicketCache true useKeyTab true doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is true principal is HTTP/myapp@TEST.MYDOMAIN.RU tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
Java config name: C:\Users\myapp\IdeaProjects\activedirectory\data\temp\krb5.conf
Loaded from Java config
>>> KdcAccessibility: reset
>>> KdcAccessibility: reset
Acquire TGT from Cache
>>>KinitOptions cache name is C:\Users\myapp\krb5cc_myapp
>> Acquire default native Credentials
default etypes for default_tkt_enctypes: 18 18 17 17 23 16 23 23.
>>> Obtained TGT from LSA: Credentials:
      client=HTTP/myapp@TEST.MYDOMAIN.RU
      server=krbtgt/TEST.MYDOMAIN.RU@TEST.MYDOMAIN.RU
    authTime=20210519095508Z
   startTime=20210519095508Z
     endTime=20210519195508Z
   renewTill=20210526065508Z
       flags=FORWARDABLE;PROXIABLE;RENEWABLE;INITIAL;PRE-AUTHENT
EType (skey)=18
   (tkt key)=18
14:07:11.119 [00000005] INFO  c.i.s.f.s.s.SessionTimeoutNotificator:176 - ID = EmployeeAuth, timesQueue size = 0, rejectedCount = 0
Principal is HTTP/myapp@TEST.MYDOMAIN.RU
14:07:11.596 [00000004] ERROR c.i.s.a.a.c.h.k.KerberosAuthenticator:71 - Some error on ticket granting
javax.security.auth.login.LoginException: No key to store
    at com.sun.security.auth.module.Krb5LoginModule.commit(Krb5LoginModule.java:1119)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
    at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
    at javax.security.auth.login.LoginContext.login(LoginContext.java:588)
    at com.mydomain.subsystem.activedirectory.auth.controller.handler.kerberos.KerberosAuthenticator.checkSecurityToken(KerberosAuthenticator.java:42)
    at com.mydomain.subsystem.activedirectory.auth.controller.handler.kerberos.KerberosAuthenticationHandler.handleRequestToken(KerberosAuthenticationHandler.java:57)
    at com.mydomain.subsystem.activedirectory.auth.controller.ADAuthController.exec(ADAuthController.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:645)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:791)
    at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
    at com.mydomain.subsystem.frontend.service.spring.filter.DisallowedMethodFilter.doFilter(DisallowedMethodFilter.java:18)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1435)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1350)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.Server.handle(Server.java:516)
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:279)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
    at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
    at java.lang.Thread.run(Thread.java:748)

第一行是Krb5LoginModule 参数。如果 storeKey false,我可以通过登录方法。之后,我试图像这样获得 outToken:

  Subject subject = lc.getSubject();
            Principal clientPrincipal = subject.getPrincipals().iterator().next();
            final GSSManager manager = GSSManager.getInstance();
            final PrivilegedExceptionAction<GSSCredential> action = () -> manager.createCredential(
                    manager.createName(clientPrincipal.getName(), GSSName.NT_USER_NAME),
                    GSSCredential.DEFAULT_LIFETIME,
                    SUPPORTED_OIDS,
                    GSSCredential.ACCEPT_ONLY);
            try {
                byte[] ticket = Base64.getDecoder().decode(token);
                final GSSContext gssContext = manager.createContext(Subject.doAs(lc.getSubject(), action));
                byte[] outToken = gssContext.acceptSecContext(ticket, 0, ticket.length);

但是我在 gssContext.acceptSecContext 上遇到了异常。

Debug is  true storeKey false useTicketCache true useKeyTab true doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is true principal is HTTP/myapp@TEST.MYDOMAIN.RU tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
Java config name: C:\Users\myapp\IdeaProjects\activedirectory\data\temp\krb5.conf
Loaded from Java config
>>> KdcAccessibility: reset
>>> KdcAccessibility: reset
Acquire TGT from Cache
>>>KinitOptions cache name is C:\Users\myapp\krb5cc_myapp
>> Acquire default native Credentials
default etypes for default_tkt_enctypes: 18 18 17 17 23 16 23 23.
>>> Obtained TGT from LSA: Credentials:
      client=HTTP/myapp@TEST.MYDOMAIN.RU
      server=krbtgt/TEST.MYDOMAIN.RU@TEST.MYDOMAIN.RU
    authTime=20210519111914Z
   startTime=20210519111914Z
     endTime=20210519211914Z
   renewTill=20210520111910Z
       flags=RENEWABLE;INITIAL;PRE-AUTHENT
EType (skey)=18
   (tkt key)=18
Principal is HTTP/myapp@TEST.MYDOMAIN.RU
Commit Succeeded 

Search Subject for SPNEGO ACCEPT cred (HTTP/myapp@TEST.MYDOMAIN.RU, sun.security.jgss.spnego.SpNegoCredElement)
Search Subject for Kerberos V5 ACCEPT cred (HTTP/myapp@TEST.MYDOMAIN.RU, sun.security.jgss.krb5.Krb5AcceptCredential)
Found ticket for HTTP/myapp@TEST.MYDOMAIN.RU to go to krbtgt/TEST.MYDOMAIN.RU@TEST.MYDOMAIN.RU expiring on Thu May 20 00:19:14 MSK 2021
Search Subject for Kerberos V5 ACCEPT cred (HTTP/myapp@TEST.MYDOMAIN.RU, sun.security.jgss.krb5.Krb5AcceptCredential)
Found ticket for HTTP/myapp@TEST.MYDOMAIN.RU to go to krbtgt/TEST.MYDOMAIN.RU@TEST.MYDOMAIN.RU expiring on Thu May 20 00:19:14 MSK 2021
Entered Krb5Context.acceptSecContext with state=STATE_NEW
14:19:36.400 [00000004] ERROR c.i.s.a.a.c.h.k.KerberosAuthenticator:71 - Some error on ticket granting
org.ietf.jgss.GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96)
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
    at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:906)
    at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:556)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
    at com.infomaximum.subsystem.activedirectory.auth.controller.handler.kerberos.KerberosAuthenticator.checkSecurityToken(KerberosAuthenticator.java:54)
    at com.infomaximum.subsystem.activedirectory.auth.controller.handler.kerberos.KerberosAuthenticationHandler.handleRequestToken(KerberosAuthenticationHandler.java:57)
    at com.infomaximum.subsystem.activedirectory.auth.controller.ADAuthController.exec(ADAuthController.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:645)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:791)
    at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
    at com.infomaximum.subsystem.frontend.service.spring.filter.DisallowedMethodFilter.doFilter(DisallowedMethodFilter.java:18)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1435)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1350)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.Server.handle(Server.java:516)
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:279)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
    at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:135)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
    at java.lang.Thread.run(Thread.java:748)
Caused by: sun.security.krb5.KrbException: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96
    at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:278)
    at sun.security.krb5.KrbApReq.<init>(KrbApReq.java:149)
    at sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.java:108)
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:829)
    ... 56 common frames omitted

这里是kerberos conf:

[libdefaults]
        default_realm = TEST.MYDOMAIN.RU
        default_tkt_enctypes = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5
        default_tgt_enctypes = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5
        permitted_enctypes   = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5
        forwardable=true
[realms]
        TEST.MYDOMAIN.RU  = {
                kdc = TEST.MYDOMAIN.RU
                default_domain = TEST.MYDOMAIN.RU
        }
[domain_realm]
        test.mydomain.ru = TEST.MYDOMAIN.RU
        .test.mydomain.ru = TEST.MYDOMAIN.RU

据我所知,无论哪种方式,此键都是从 Subject 填充的。这不应该是 TGT 缓存中的会话密钥吗?如果是这样,为什么它没有被填充?或者也许我错过了一些基本面?如果使用 keytab,一切正常。

AllowTGTSessionKey 显然是 1。

提前致谢,我是新手。

编辑:我试过使用 java kinit 缓存,这里是异常。无论出于何种原因,看起来又像 LSA。

Loaded from Java config
>>> KdcAccessibility: reset
>>> KdcAccessibility: reset
Acquire TGT from Cache
>>>KinitOptions cache name is C:\Users\myapp\krb5cc_myapp
>>>DEBUG <CCacheInputStream>  client principal is HTTP/myapp@TEST.MYDOMAIN.RU
>>>DEBUG <CCacheInputStream> server principal is krbtgt/TEST.MYDOMAIN.RU@TEST.MYDOMAIN.RU
>>>DEBUG <CCacheInputStream> key type: 18
>>>DEBUG <CCacheInputStream> auth time: Fri May 21 15:45:35 MSK 2021
>>>DEBUG <CCacheInputStream> start time: Fri May 21 15:45:35 MSK 2021
>>>DEBUG <CCacheInputStream> end time: Sat May 22 01:45:35 MSK 2021
>>>DEBUG <CCacheInputStream> renew_till time: null
>>> CCacheInputStream: readFlags()  FORWARDABLE; PROXIABLE; INITIAL; PRE_AUTH;
Host address is /here_is_IP
Host address is /here_is_MAC
>>> KrbCreds found the default ticket granting ticket in credential cache.
>>> Obtained TGT from LSA: Credentials:
      client=HTTP/myapp@TEST.MYDOMAIN.RU
      server=krbtgt/TEST.MYDOMAIN.RU@TEST.MYDOMAIN.RU
    authTime=20210521124535Z
   startTime=20210521124535Z
     endTime=20210521224535Z
   renewTill=null
       flags=FORWARDABLE;PROXIABLE;INITIAL;PRE-AUTHENT
EType (skey)=18
   (tkt key)=18
Principal is HTTP/myapp@TEST.MYDOMAIN.RU
Commit Succeeded 

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 ticket for HTTP/myapp@TEST.MYDOMAIN.RU to go to krbtgt/TEST.MYDOMAIN.RU@TEST.MYDOMAIN.RU expiring on Sat May 22 01:45:35 MSK 2021
Search Subject for Kerberos V5 ACCEPT cred (<<DEF>>, sun.security.jgss.krb5.Krb5AcceptCredential)
Found ticket for HTTP/myapp@TEST.MYDOMAIN.RU to go to krbtgt/TEST.MYDOMAIN.RU@TEST.MYDOMAIN.RU expiring on Sat May 22 01:45:35 MSK 2021
Entered Krb5Context.acceptSecContext with state=STATE_NEW
16:34:02.022 [00000004] ERROR c.i.s.a.a.c.h.k.KerberosAuthenticator:65 - Some error on ticket granting
org.ietf.jgss.GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96)
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
    at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:906)
    at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:556)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
    at com.mydomain.subsystem.activedirectory.auth.controller.handler.kerberos.KerberosAuthenticator.checkSecurityToken(KerberosAuthenticator.java:48)
    at com.mydomain.subsystem.activedirectory.auth.controller.handler.kerberos.KerberosAuthenticationHandler.handleRequestToken(KerberosAuthenticationHandler.java:57)
    at com.mydomain.subsystem.activedirectory.auth.controller.ADAuthController.exec(ADAuthController.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:645)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:791)
    at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
    at com.mydomain.subsystem.frontend.service.spring.filter.DisallowedMethodFilter.doFilter(DisallowedMethodFilter.java:18)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1435)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1350)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.Server.handle(Server.java:516)
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:279)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
    at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
    at java.lang.Thread.run(Thread.java:748)
Caused by: sun.security.krb5.KrbException: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96
    at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:278)
    at sun.security.krb5.KrbApReq.<init>(KrbApReq.java:149)
    at sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.java:108)
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:829)
    ... 52 common frames omitted

编辑: 我已经指定了 ticketCache 属性以使用 java kinit 缓存路径,现在 LSA 被忽略了。但异常仍然相同 - sun.security.krb5.KrbException: Invalid argument (400) - 找不到适当类型的密钥来解密 AP REP - 使用 HMAC SHA1-96 的 AES256 CTS 模式。

如果有任何问题,我要做的是代表同一 AD 中的服务帐户验证来自某个 AD 用户的令牌。我不能 100% 确定它是如何工作的,但是使用 keytab 一切都很好。

【问题讨论】:

  • 您使用的是非常旧的 Java 版本,在 security.policy 中未启用无限安全性。你改变它,AES 就可以工作了。
  • 我之前已经仔细检查过了——我是无限的@Michael-O
  • 分享你的 jaas 配置文件。
  • 我们没有单独的conf文件,一切都是通过HashMap存储和应用的。所有选项: Debug is true storeKey false useTicketCache true useKeyTab true doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is true principal is HTTP/myapp@TEST.MYDOMAIN.RU tryFirstPass is false useFirstPass is false storePass is false clearPass is false 一半这是一个默认值。

标签: java kerberos gssapi kerberos-delegation


【解决方案1】:

算了,这些天您几乎无法通过 Windows API 访问会话密钥。 JGSS 无法使用。您基本上有两种选择:

  • 从 Java 执行 kinit 并使用该 TGT
  • 通过 C 或 JNA 使用 SSPI

【讨论】:

    【解决方案2】:

    Java 13 introduced 在 JDK 中为 Windows 自己的 GSS API (SSPI) 提供内置支持。

    它是backported to Java 11.0.10 - 我建议你更新你的 JDK。

    【讨论】:

    • 好吧,我在合并前后回顾了这个实现。我认为它是 beta 质量,Max 没有时间再次审查它。它可以工作,但味道不好......此外,如果你使用登录上下文,你就会失败。
    【解决方案3】:

    “找不到合适类型的密钥来解密 AP REP..”

    当您的服务器无法解密票证时,通常会发生该错误。但是您已经提到存在无限的加密强度。如果可能,请发布提及加密算法的 krb5.conf 文件。

    我相信你的最后一行很重要 -

    如果有任何问题,我要做的是验证令牌 来自某个 AD 用户,代表同一 AD 中的服务帐户。我是 不是 100% 确定这就是它的工作原理,但使用 keytab 一切都是 美好的。 这意味着 keytab 拥有可以成功解密令牌的密钥。

    以下内容值得研究:

    1. keytab 用户和服务用户是否相同?
    2. 如果它们不同,您是否将“服务”附加到您正在使用的服务帐户? (setspn -s )
    3. 请验证 Windows 中的以下设置 -“网络安全:配置 Kerberos 允许的加密类型”

    【讨论】:

      猜你喜欢
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多