bedrin / kerb4j Goto Github PK
View Code? Open in Web Editor NEWThis project forked from ocbaker/jaaslounge-decoding
Kerberos and SPNEGO in Java done right
License: GNU Lesser General Public License v2.1
This project forked from ocbaker/jaaslounge-decoding
Kerberos and SPNEGO in Java done right
License: GNU Lesser General Public License v2.1
An LDAP Injection vulnerability exists in the LdapIdentityBackend of Apache Kerby before 2.0.3.
https://nvd.nist.gov/vuln/detail/CVE-2023-25613
GHSA-337f-xr2x-6fcf
Kerb4j currently is dependent on Apache Kerby 2.0.2.
Do we have the plan to upgrade Kerby to 2.0.3 to mitigate CVE-2023-25613?
Thank you.
Hi,
First of all thanks for all the work, it really saved me some time. Especially the SID retrieval part directly from the kerberos ticket.
Looking into that, I seem to have an issue on my end. Not sure where it comes from and if it could be an issue from the ticket decoding. When looking at the SID retrieved from a user of my app, I get some stuff in the resourceGroupSids part of the PacLogonInfo. These info are the local/applicative rights related to the user so that's good, but it seems the SIDs retrieved are not entirely correct.
Here's an example of what I've got (no real data):
Basically it seems some data is duplicated while constructing the SID. In summary I have :
-> correct SID: S-1-X-SOMESTUFF-9999
-> SID in resourceGroupSids: S-1-X-SOMESTUFF-SOMESTUFF-9999
I'm not too familiar with all these mechanisms, so I don't know if something is indeed wrong here of if I'm mistaken somehow?
I checked for SIDs retrieved in PacLogonInfo groupSids and these ones are correct.
Cheers,
Sylvain
I have a spring security kerberos secured web server.
I am working on a Swing based client for which I have the following requirement:
If this library is not capable of doing so then any pointers in the direction that this can be achieved will be appreciated.
Things that I have tried to look into as an alternative:
Support at least two latest major releases
The last version in Maven central is 0.8. Forgot to publish version 0.9?
Consider adding a way to flush cache on error
We use kerb4j successfully (thanks!) but the kerb4j-common library keeps coming up on thirdparty version and security issue reviews in our company.
I looked into the dependencies and the very large dependency tree of kerb4j-common is caused by it dependending on org.apache.kerby:kerb-simplekdc
. This appears to be a KDC test server implementation that has a bunch of additional dependencies.
kerb4j-common only needs these dependencies for unit tests.
I have locally cloned the kerb4j repository and and set the dependency to <scope>test</scope>
for kerb4j-common and I have additionally added the dependency (as a test dependency) to the following projects:
After this change, a mvn clean install
on the current master version builds and tests fine.
When trying to compile with Java 9, I get split package errors the moment I import kerb4j
error: the unnamed module reads package com.kerb4j.client from both kerb4j.client and kerb4j.common
error: the unnamed module reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java8 and kerb4j.base64.common
error: the unnamed module reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java8 and kerb4j.base64.java7
error: module kerb4j.base64.java7 reads package com.kerb4j.client from both kerb4j.common and kerb4j.client
error: module kerb4j.base64.java7 reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.common
error: module kerb4j.base64.java7 reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.java8
error: module kerb4j.base64.java8 reads package com.kerb4j.client from both kerb4j.common and kerb4j.client
error: module kerb4j.base64.java8 reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.common
error: module kerb4j.base64.java8 reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.java8
error: module kerb4j.base64.common reads package com.kerb4j.client from both kerb4j.common and kerb4j.client
error: module kerb4j.base64.common reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.common
error: module kerb4j.base64.common reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.java8
error: module kerb4j.client reads package com.kerb4j.client from both kerb4j.common and kerb4j.client
error: module kerb4j.client reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.common
error: module kerb4j.client reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.java8
error: module kerb4j.common reads package com.kerb4j.client from both kerb4j.client and kerb4j.common
error: module kerb4j.common reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.common
error: module kerb4j.common reads package com.kerb4j.common.util.base64 from both kerb4j.base64.java7 and kerb4j.base64.java8
Essentially looking for example where we can do keytab based authentication for proxy first before connecting to target url and user / pwd basic authentication for target url
I appreciate the work you did regarding the proper kerberos authentication, especially addressing the group membership issues.
This issue is a Change Request to support JEE 9+ with jakarta namespace and the recently released Spring Kerberos 2.x, so the first statement in the Kerb4J could be true: "Industry standard library for working with Kerberos/SPNEGO authentication in Java in 2023+."
Please, let me know if such CR is planned and if it is, then what would be the target date.
ContextFlags is parsed as Asn1Flags while it should be Asn1BitString
java.lang.ArrayIndexOutOfBoundsException: 1
at org.apache.kerby.asn1.type.Asn1Flags.value2Flags(Asn1Flags.java:118)
at org.apache.kerby.asn1.type.Asn1Flags.setValue(Asn1Flags.java:63)
at org.apache.kerby.asn1.type.Asn1Flags.setValue(Asn1Flags.java:31)
at org.apache.kerby.asn1.type.Asn1BitString.toValue(Asn1BitString.java:84)
at org.apache.kerby.asn1.type.Asn1Flags.toValue(Asn1Flags.java:124)
at org.apache.kerby.asn1.type.Asn1Simple.decodeBody(Asn1Simple.java:100)
at org.apache.kerby.asn1.type.Asn1Encodeable.decode(Asn1Encodeable.java:224)
at org.apache.kerby.asn1.type.Asn1Encodeable.taggedDecode(Asn1Encodeable.java:299)
at org.apache.kerby.asn1.Asn1Binder.bindWithTagging(Asn1Binder.java:49)
at org.apache.kerby.asn1.type.Asn1CollectionType.attemptBinding(Asn1CollectionType.java:127)
at org.apache.kerby.asn1.type.Asn1CollectionType.decodeBody(Asn1CollectionType.java:111)
at org.apache.kerby.asn1.type.Asn1Encodeable.decode(Asn1Encodeable.java:224)
at com.kerb4j.spnego.SpnegoInitToken.<init>(SpnegoInitToken.java:58)
As the Spring Security Kerberos project (https://github.com/spring-projects/spring-security-kerberos) is lacking support, and this could be a more modern solution - I would like to see a release containing support for Spring Security 5 directly embeddable into a Spring boot 2.X project.
Currently when including kerb4j there is dependencies to Spring Security 3.X, 4.X and 5.X if included in a Spring Boot 2.X project. This is a recipe for disaster in a not so far future.
Using this code based kerb4j, the following error is produced when trying to access /hello using Chrome:
2022-01-19 13:37:39.931 DEBUG 1543557 --- [http-nio-9125-exec-2] o.s.security.web.FilterChainProxy : Securing GET /hello
2022-01-19 13:37:39.931 DEBUG 1543557 --- [http-nio-9125-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-01-19 13:37:40.003 DEBUG 1543557 --- [http-nio-9125-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-01-19 13:37:40.003 DEBUG 1543557 --- [http-nio-9125-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2022-01-19 13:37:40.009 ERROR 1543557 --- [http-nio-9125-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exceptionjava.lang.RuntimeException: javax.security.auth.login.LoginException: Checksum failed
at com.kerb4j.common.jaas.sun.Krb5LoginContext.loginWithKeyTab(Krb5LoginContext.java:28) ~[kerb4j-common-0.1.2.jar!/:na]
at com.kerb4j.client.SpnegoClient$3.call(SpnegoClient.java:174) ~[kerb4j-common-0.1.2.jar!/:na]
at com.kerb4j.client.SpnegoClient$3.call(SpnegoClient.java:171) ~[kerb4j-common-0.1.2.jar!/:na]
at com.kerb4j.client.SpnegoClient$1.call(SpnegoClient.java:93) ~[kerb4j-common-0.1.2.jar!/:na]
at com.kerb4j.client.SpnegoClient$1.call(SpnegoClient.java:89) ~[kerb4j-common-0.1.2.jar!/:na]
at com.kerb4j.client.SpnegoClient.getSubject(SpnegoClient.java:219) ~[kerb4j-common-0.1.2.jar!/:na]
at com.kerb4j.client.SpnegoClient.createAcceptContext(SpnegoClient.java:294) ~[kerb4j-common-0.1.2.jar!/:na]
at com.kerb4j.server.spring.jaas.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:66) ~[kerb4j-server-spring-security-0.1.2.jar!/:na]
at com.kerb4j.server.spring.SpnegoAuthenticationProvider.authenticate(SpnegoAuthenticationProvider.java:108) ~[kerb4j-server-spring-security-0.1.2.jar!/:na]
at com.kerb4j.server.spring.SpnegoAuthenticationProvider.authenticate(SpnegoAuthenticationProvider.java:60) ~[kerb4j-server-spring-security-0.1.2.jar!/:na]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.5.2.jar!/:5.5.2]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:201) ~[spring-security-core-5.5.2.jar!/:5.5.2]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:518) ~[spring-security-config
-5.5.2.jar!/:5.5.2]
at com.kerb4j.server.spring.SpnegoAuthenticationProcessingFilter.doFilterInternal(SpnegoAuthenticationProcessingFilter.java:165) ~[kerb4j-server-spring-security-0.1.2.jar!/:na]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:218) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.5.2.jar!/:5.5.2]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.10.jar!/:5.3.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.53.jar!/:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.53.jar!/:na]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_292]
Caused by: javax.security.auth.login.LoginException: Checksum failed
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:808) ~[na:1.8.0_292]
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:618) ~[na:1.8.0_292]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_292]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_292]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_292]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_292]
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755) ~[na:1.8.0_292]
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195) ~[na:1.8.0_292]
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682) ~[na:1.8.0_292]
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680) ~[na:1.8.0_292]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_292]
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) ~[na:1.8.0_292]
at javax.security.auth.login.LoginContext.login(LoginContext.java:587) ~[na:1.8.0_292]
at com.kerb4j.common.jaas.sun.Krb5LoginContext.loginWithKeyTab(Krb5LoginContext.java:24) ~[kerb4j-common-0.1.2.jar!/:na]
... 68 common frames omitted
Caused by: sun.security.krb5.KrbCryptoException: Checksum failed
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:102) ~[na:1.8.0_292]
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:94) ~[na:1.8.0_292]
at sun.security.krb5.EncryptedData.decrypt(EncryptedData.java:175) ~[na:1.8.0_292]
at sun.security.krb5.KrbAsRep.decrypt(KrbAsRep.java:150) ~[na:1.8.0_292]
at sun.security.krb5.KrbAsRep.decryptUsingKeyTab(KrbAsRep.java:121) ~[na:1.8.0_292]
at sun.security.krb5.KrbAsReqBuilder.resolve(KrbAsReqBuilder.java:310) ~[na:1.8.0_292]
at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:498) ~[na:1.8.0_292]
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:780) ~[na:1.8.0_292]
... 81 common frames omitted
Caused by: java.security.GeneralSecurityException: Checksum failed
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(AesDkCrypto.java:451) ~[na:1.8.0_292]
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(AesDkCrypto.java:272) ~[na:1.8.0_292]
at sun.security.krb5.internal.crypto.Aes256.decrypt(Aes256.java:76) ~[na:1.8.0_292]
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:100) ~[na:1.8.0_292]
... 88 common frames omitted
The Chrome user is prompted with a basic auth box.
It works using this same code after changing as instructed in the commented code to use spring-security-kerberos, That is, the active directory username is shown when navigating to /hello.
I'm working on using kerb4j to access kerberos authenticated APIs and as part of the work, I've created an API Handler class which has a class method, createKerberosAuthToken()
def createKerberosAuthToken(){
if (!this.kerberosPrincipal) {
throw new Exception("Principal required when executing kerberos authenticated API calls")
}
if (!this.kerberosKeytabPath) {
throw new Exception("Keytab path required when executing kerberos authenticated API calls")
}
try {
SpnegoClient spnegoClient = new SpnegoClient()
SpnegoClient.loginWithKeyTab(this.kerberosPrincipal, this.kerberosKeytabPath)
URL url = new URL("${this.apiUrl.getProtocol()}://${this.apiUrl.getHost()}")
SpnegoContext context = spnegoClient.createContext(url)
return context.createTokenAsAuthroizationHeader()
} catch (Exception e) {
println "KrbConf: ${System.getProperty("java.security.krb5.conf")}"
println "KrbConf: ${System.getProperty("java.security.krb5.realm")}"
println "KrbConf: ${System.getProperty("java.security.krb5.kdc")}"
throw new Exception("Error encountered creating kerberos authorization header:\n${e}")
}
}
On a development box configured with a known good krb5.conf at /etc/krb5.conf, this works like butter.
However, I wanted to see if it would be feasible to using this same approach on a system which wasn't configured with kerberos (a Jenkins master in this case), and I get the following error:
java.lang.Exception: Error encountered creating kerberos authorization header:
GSSException: Invalid name provided (Mechanism level: KrbException: Cannot locate default realm)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:77)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:84)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:247)
at com.redhat.contra.productization.ApiHandler.createKerberosAuthToken(ApiHandler.groovy:411)
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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
at com.redhat.contra.productization.ApiHandler.doHttpPostRequest(file:/var/lib/jenkins/jobs/foo/builds/121/libs/rhprod/src/com/redhat/contra/productization/ApiHandler.groovy:362)
at com.redhat.contra.productization.factory2.WaiverDb.createWaivers(file:/var/lib/jenkins/jobs/foo/builds/121/libs/rhprod/src/com/redhat/contra/productization/factory2/WaiverDb.groovy:95)
at createWaiver.call(/var/lib/jenkins/jobs/foo/builds/121/libs/rhprod/vars/createWaiver.groovy:52)
at WorkflowScript.run(WorkflowScript:53)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:77)
at sun.reflect.GeneratedMethodAccessor238.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
at com.cloudbees.groovy.cps.Next.step(Next.java:83)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:182)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
I've attempted to specify the krb5.conf location by setting the "java.security.krb5.conf", and I've verified that it's being set.
Is it feasible to achieve what I'm trying to do with kerb4j?
Hi,
So basically i want to execute a SAP rest request, but the SAP server is protected by SPNEGO.
When using basically the example code snippet, i get a successfull authentication with Kerberos,
but the SAP is unhappy, as it can't find valid credentials in teh Authorisation header.
So when i have different credentials for SPNEGO and SAP, how do i add/switch my authentication after i logged into SPNEGO?
Hi
I would like to use SpengoClient to create a context and create a header that I can use with an arbitrary HttpConnection or websocket connection
However the SpnegoClient constructor which takes LoginConfig supplier is protected. This makes it very awkward.
Could you make this public?
Or perhaps provide a utility method which takes a config section name and a url and returns the token authorization header string.
This is my extremely brittle workaround which will obviously have problems with modules
private static SpnegoClient spnegoClientForLogin(String s) throws ReflectiveOperationException {
Constructor<SpnegoClient> ctor = SpnegoClient.class.getDeclaredConstructor(Callable.class);
ctor.setAccessible(true);
return ctor.newInstance((Callable<LoginContext>) () -> {
try {
return new LoginContext(s);
} catch (LoginException e) {
throw new RuntimeException(e);
}
});
}
String authHeader = spnegoClientForLogin(sectionName).createContext(url).createTokenAsAuthorizationHeader();
Thank you
Hi there,
I'm trying to get this work with Spring Security and Vaadin 8.
Is there an example project which I can take a look at?
Currently I have the following setup in the application-context.xml
:
<sec:http entry-point-ref="spnegoEntryPoint">
<sec:intercept-url pattern="/**" access="hasRole('Authenticated')"/>
<sec:custom-filter ref="spnegoAuthenticationProcessingFilter"
position="BASIC_AUTH_FILTER"/>
<sec:form-login login-page="/login.html" default-target-url="/secure/index.jsp"/>
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="kerberosServiceAuthenticationProvider"/> <!-- Used with SPNEGO -->
<sec:authentication-provider user-service-ref="dummyUserDetailsService"/> <!-- Used with form login -->
</sec:authentication-manager>
<bean id="kerberosServiceAuthenticationProvider"
class="com.kerb4j.server.spring.SpnegoAuthenticationProvider">
<property name="ticketValidator">
<bean class="com.kerb4j.server.spring.jaas.sun.SunJaasKerberosTicketValidator">
<property name="servicePrincipal" value="HTTP/[email protected]"/>
<property name="keyTabLocation" value="file:C:\Temp\foobar.keytab"/>
</bean>
</property>
<property name="userDetailsService" ref="dummyUserDetailsService"/>
</bean>
<bean id="dummyUserDetailsService" class="com.company.DummyUserDetailsService"/>
<bean id="spnegoEntryPoint" class="com.kerb4j.server.spring.SpnegoEntryPoint"/>
And the web.xml has:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The keytab file is correct, and the servicePrincipal
here matches the one in the keytab file. Still, the app throws the Exception in the title, with the following stacktrace:
2021-02-25 13:09:54 WARN SpnegoAuthenticationProcessingFilter:169 - Negotiate Header was invalid: Negotiate <TOKEN>
org.springframework.security.authentication.BadCredentialsException: Kerberos validation not successful
at com.kerb4j.server.spring.jaas.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:83)
at com.kerb4j.server.spring.SpnegoAuthenticationProvider.authenticate(SpnegoAuthenticationProvider.java:108)
at com.kerb4j.server.spring.SpnegoAuthenticationProvider.authenticate(SpnegoAuthenticationProvider.java:60)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
at com.kerb4j.server.spring.SpnegoAuthenticationProcessingFilter.doFilterInternal(SpnegoAuthenticationProcessingFilter.java:165)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
at com.mycompany.frontend.security.config.HttpSessionFilterBean.doFilter(HttpSessionFilterBean.java:23)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:201)
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.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
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.session.SessionHandler.doScope(SessionHandler.java:1594)
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.ContextHandlerCollection.handle(ContextHandlerCollection.java:191)
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:273)
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.run(EatWhatYouKill.java:129)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:375)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:773)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:905)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
at java.security.jgss/sun.security.jgss.GSSHeader.<init>(GSSHeader.java:97)
at java.security.jgss/sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:325)
at java.security.jgss/sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:303)
at java.security.jgss/sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:905)
at java.security.jgss/sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:556)
at java.security.jgss/sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:361)
at java.security.jgss/sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:303)
at com.kerb4j.client.SpnegoContext.acceptToken(SpnegoContext.java:55)
at com.kerb4j.server.spring.jaas.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:68)
... 63 more
If I debug the app at the GSSHeader.java:97
, the the variable tag
has the value of 78
<- my guess is that the app fails 'cause of this.
Thanks for any help,
Also expose all private fields via getters where applicable, for example in SunJaasKerberosTicketValidator
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.