I'm trying to setup kerberos authentication in a Java web-app running in a Tomcat on Linux. I'm using the spring security kerberos extension. I'm using:
- jdk 1.7u75
- spring-security-kerberos 1.0.0.RELEASE
- MS Active Directory
On my local development machine (windows) everything runs fine. But after deploying the app to a linux machine authentication is no longer working. I strongly suspect that something is wrong with my Kerberos configuration :
[libdefaults]
default_realm = INT.MYCOMPANY.DE
ccache_type=4
kdc_tymesync=1
forwardable=true
proxiable=true
[realms]
INT.MYCOMPANY.DE = {
admin_server = xyz.mycompany.de
kdc = xyz.mycompany.de
}
[domain_realm]
.INT.MYCOMPANY.DE = INT.MYCOMPANY.DE
int.mycompany.de = INT.MYCOMPANY.DE
.int.mycompany.de = INT.MYCOMPANY.DE
.mycompany.de = INT.MYCOMPANY.DE
mycompany.de = INT.MYCOMPANY.DE
[logging]
#kdc = console
(server and realm name changed)
Spring security config:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="file:${externalPropertiesPath}/edlgui.properties" />
<authentication-manager alias="authenticationManager">
<authentication-provider ref="kerberosAuthenticationProvider" />
</authentication-manager>
<http use-expressions="true">
<intercept-url pattern="/login.jsp" access="permitAll" />
<intercept-url pattern="/admin/**" access="hasRole('${edl.gui.authorization.requiredrole}')" />
<form-login login-page="/login.jsp" username-parameter="username" password-parameter="password" default-target-url="/admin"/>
<logout logout-url="/logout" logout-success-url="/login.jsp" />
<http-basic />
<access-denied-handler ref="edlGuiAccessDeniedHandler"/>
</http>
<beans:bean id="edlGuiAccessDeniedHandler" class="edl.security.EdlGuiAccessDeniedHandler">
<beans:constructor-arg value="/login.jsp"/>
</beans:bean>
<beans:bean id="kerberosAuthenticationProvider" class="org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider">
<beans:property name="kerberosClient">
<beans:bean class="org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient">
<beans:property name="debug" value="false" />
</beans:bean>
</beans:property>
<!-- TODO replace dummy user service -->
<beans:property name="userDetailsService" ref="ldapUserDetailsService" />
</beans:bean>
<beans:bean class="org.springframework.security.kerberos.authentication.sun.GlobalSunJaasKerberosConfig">
<beans:property name="debug" value="false" />
<!-- externalPropertiesPath path = /opt/pksvc/tomcat/current/conf -->
<beans:property name="krbConfLocation" value="file:${externalPropertiesPath}/krb5.conf"/>
</beans:bean>
<!-- Get User Details via LDAP -->
<!-- It would be nice to do this via Kerberos, however that requires a keytab -->
<ldap-user-service id="ldapUserDetailsService"
server-ref="activeDirectoryLdap"
user-search-base="${edl.gui.ldap.usersearchbase}"
user-search-filter="${edl.gui.ldap.usersearchfilter}"
group-search-base="${edl.gui.ldap.groupsearchbase}"
group-role-attribute="${edl.gui.ldap.grouproleattribute}"
group-search-filter="${edl.gui.ldap.groupsearchfilter}"
user-details-class="person"/>
<ldap-server id="activeDirectoryLdap"
url="${edl.gui.ldap.url}"
manager-dn="${edl.gui.ldap.managerdn}"
manager-password="${edl.gui.ldap.managerpw}"
root="${edl.gui.ldap.root}"/>
</beans:beans>
When I try to login the only thing I see from the kerberos debug output is:
Java config name: file:/opt/pksvc/tomcat/current/conf/krb5.conf
getRealmFromDNS: trying mycompany.de
(I would expect to see 'KrbAsReq creating message' and 'KrbKdcReq send' entries)
And from spring:
2015-08-04 10:07:42.986 DEBUG o.s.security.web.FilterChainProxy - /j_spring_security_check at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-08-04 10:07:42.986 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2015-08-04 10:07:42.986 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@64656737. A new one will be created.
2015-08-04 10:07:42.986 DEBUG o.s.security.web.FilterChainProxy - /j_spring_security_check at position 2 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2015-08-04 10:07:42.986 DEBUG o.s.security.web.FilterChainProxy - /j_spring_security_check at position 3 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
2015-08-04 10:07:42.987 DEBUG o.s.security.web.FilterChainProxy - /j_spring_security_check at position 4 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2015-08-04 10:07:42.987 DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Request is to process authentication
2015-08-04 10:07:42.987 DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider
2015-08-04 10:07:42.987 DEBUG o.s.s.k.a.sun.SunJaasKerberosClient - Trying to authenticate KieselGun with Kerberos
2015-08-04 10:07:42.993 DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Kerberos authentication failed
2015-08-04 10:07:42.993 DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
2015-08-04 10:07:42.993 DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@72f106b0
2015-08-04 10:07:42.993 DEBUG o.s.s.w.a.SimpleUrlAuthenticationFailureHandler - Redirecting to /login.jsp
2015-08-04 10:07:42.993 DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to '/edl-gui/login.jsp'
2015-08-04 10:07:42.993 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2015-08-04 10:07:42.994 DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
2015-08-04 10:07:43.042 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-08-04 10:07:43.043 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2015-08-04 10:07:43.043 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@64656737. A new one will be created.
2015-08-04 10:07:43.043 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 2 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2015-08-04 10:07:43.043 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 3 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
2015-08-04 10:07:43.043 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 4 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2015-08-04 10:07:43.043 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 5 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2015-08-04 10:07:43.043 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2015-08-04 10:07:43.044 DEBUG o.s.s.w.s.DefaultSavedRequest - pathInfo: both null (property equals)
2015-08-04 10:07:43.044 DEBUG o.s.s.w.s.DefaultSavedRequest - queryString: both null (property equals)
2015-08-04 10:07:43.044 DEBUG o.s.s.w.s.DefaultSavedRequest - requestURI: arg1=/edl-gui/admin; arg2=/edl-gui/login.jsp (property not equals)
2015-08-04 10:07:43.044 DEBUG o.s.s.w.s.HttpSessionRequestCache - saved request doesn't match
2015-08-04 10:07:43.044 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2015-08-04 10:07:43.044 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2015-08-04 10:07:43.044 DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@6faa3d44: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff4c9c: RemoteIpAddress: 172.20.65.226; SessionId: F2C563CA5780A3024AE7D89390CE0AB1; Granted Authorities: ROLE_ANONYMOUS'
2015-08-04 10:07:43.044 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
2015-08-04 10:07:43.044 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2015-08-04 10:07:43.045 DEBUG o.s.security.web.FilterChainProxy - /login.jsp at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2015-08-04 10:07:43.045 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login.jsp'; against '/login.jsp'
2015-08-04 10:07:43.045 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /login.jsp; Attributes: [permitAll]
2015-08-04 10:07:43.045 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@6faa3d44: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff4c9c: RemoteIpAddress: 172.20.65.226; SessionId: F2C563CA5780A3024AE7D89390CE0AB1; Granted Authorities: ROLE_ANONYMOUS
2015-08-04 10:07:43.045 DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@265c45f7, returned: 1
2015-08-04 10:07:43.045 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
2015-08-04 10:07:43.045 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
2015-08-04 10:07:43.045 DEBUG o.s.security.web.FilterChainProxy - /login.jsp reached end of additional filter chain; proceeding with original chain
2015-08-04 10:07:43.046 DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
2015-08-04 10:07:43.046 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2015-08-04 10:07:43.046 DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
So it seems the user gets authenticated as anonymous, after which I get back to the login page since anonymous users have no access.
Can anyone tell me what's wrong with my configuration? Or how I could further analyse this?
getRealmFromDNS: trying int.hlg.de [Krb5LoginModule] authentication failed Cannot locate default realm
– ZulemazulloJava config name: file:/opt/pksvc/tomcat/current/conf/krb5.conf
that this file is really used? – Zulemazullofile:///opt/pksvc/tomcat/current/conf/krb5.conf
– JauchJava config name: file:///opt/pksvc/tomcat_edl/current/conf/krb5.conf getRealmFromDNS: trying mycompany.de [Krb5LoginModule] authentication failed Cannot locate default realm
– Zulemazullodummy user service
(you use ldapUserDetailsService instead) is used to add user to spring sec context. However this is where it gets tricky, if your dev win machine is part of AD domain, you may already have a valid kerberos TGT in local cache and jdk may try to use that. Think I need to try some of these scenarios in my local vm's. – Mange