diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProvider.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProvider.java index 3e37004..36e3221 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProvider.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,21 +21,53 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter; + +/** + *

Authentication Provider which validates Kerberos Service Tickets + * or SPNEGO Tokens (which includes Kerberos Service Tickets).

+ * + *

It needs a KerberosTicketValidator, which contains the + * code to validate the ticket, as this code is different between + * SUN and IBM JRE.
+ * It also needs an UserDetailsService to load the user properties + * and the GrantedAuthorities, as we only get back the username + * from Kerbeos

+ * + * You can see an example configuration in SpnegoAuthenticationProcessingFilter. + * + * @author Mike Wiesner + * @since 1.0 + * @version $Id$ + * @see KerberosTicketValidator + * @see UserDetailsService + * @see SpnegoAuthenticationProcessingFilter + */ public class KerberosServiceAuthenticationProvider implements AuthenticationProvider { private KerberosTicketValidator ticketValidator; private UserDetailsService userDetailsService; + + /** The UserDetailsService to use, for loading the user properties + * and the GrantedAuthorities. + */ public void setUserDetailsService(UserDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } + /** The KerberosTicketValidator to use, for validating + * the Kerberos/SPNEGO tickets. + */ public void setTicketValidator(KerberosTicketValidator ticketValidator) { this.ticketValidator = ticketValidator; } + /* (non-Javadoc) + * @see org.springframework.security.authentication.AuthenticationProvider#authenticate(org.springframework.security.core.Authentication) + */ @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { @@ -46,6 +78,9 @@ public class KerberosServiceAuthenticationProvider implements return new KerberosServiceRequestToken(userDetails, userDetails.getAuthorities(), token); } + /* (non-Javadoc) + * @see org.springframework.security.authentication.AuthenticationProvider#supports(java.lang.Class) + */ @Override public boolean supports(Class auth) { return KerberosServiceRequestToken.class.isAssignableFrom(auth); diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceRequestToken.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceRequestToken.java index b36728b..dcaaee7 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceRequestToken.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceRequestToken.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,19 +21,36 @@ import java.util.List; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter; /** - * Holds the Kerberos/SPNEGO token for requesting a kerberized service Will - * mostly be created in ...Filter and authenticated in - * KerberosServiceAuthenticationProvider + * Holds the Kerberos/SPNEGO token for requesting a kerberized service + * and is also the output of KerberosServiceAuthenticationProvider.
+ * Will mostly be created in SpnegoAuthenticationProcessingFilter + * and authenticated in KerberosServiceAuthenticationProvider. + * + * This token cannot be re-authenticated, as you will get a Kerberos Reply error. * * @author Mike Wiesner * @since 1.0 - * @version $Id: $ + * @version $Id$ + * @see KerberosServiceAuthenticationProvider + * @see SpnegoAuthenticationProcessingFilter */ public class KerberosServiceRequestToken extends AbstractAuthenticationToken { + private static final long serialVersionUID = 395488921064775014L; + private final byte[] token; + private final Object principal; + + /** Creates an authenticated token, normally used as an output of an authentication provider. + * @param principal the user principal (mostly of instance UserDetails + * @param authorities the authorities which are granted to the user + * @param token the Kerberos/SPNEGO token + * @see UserDetails + */ public KerberosServiceRequestToken(Object principal, List authorities, byte[] token) { super(authorities); this.token = token; @@ -41,16 +58,12 @@ public class KerberosServiceRequestToken extends AbstractAuthenticationToken { super.setAuthenticated(true); } - private static final long serialVersionUID = 395488921064775014L; - private final byte[] token; - private final Object principal; - /** * Creates an unauthenticated instance which should then be authenticated by - * KerberosServiceAuthenticationProvider + * KerberosServiceAuthenticationProvider/code> * - * @param token - * Kerberos/SPNEGO token + * @param token Kerberos/SPNEGO token + * @see KerberosServiceAuthenticationProvider */ public KerberosServiceRequestToken(byte[] token) { super(null); @@ -58,6 +71,9 @@ public class KerberosServiceRequestToken extends AbstractAuthenticationToken { this.principal = null; } + /** + * Calculates hashcode based on the Kerberos token + */ @Override public int hashCode() { final int prime = 31; @@ -66,6 +82,9 @@ public class KerberosServiceRequestToken extends AbstractAuthenticationToken { return result; } + /** + * equals() is based only on the Kerberos token + */ @Override public boolean equals(Object obj) { if (this == obj) @@ -80,16 +99,24 @@ public class KerberosServiceRequestToken extends AbstractAuthenticationToken { return true; } + /* (non-Javadoc) + * @see org.springframework.security.core.Authentication#getCredentials() + */ @Override public Object getCredentials() { return null; } + /* (non-Javadoc) + * @see org.springframework.security.core.Authentication#getPrincipal() + */ @Override public Object getPrincipal() { return this.principal; } + /** Returns the Kerberos token + */ public byte[] getToken() { return this.token; } diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosTicketValidator.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosTicketValidator.java index 677d1fb..9dd9551 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosTicketValidator.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosTicketValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,24 @@ package org.springframework.security.extensions.kerberos; +import org.springframework.security.authentication.BadCredentialsException; + /** + * Implementations of this interface are used in + * {@link KerberosServiceAuthenticationProvider} to validate a Kerberos/SPNEGO Ticket. * * @author Mike Wiesner * @since 1.0 * @version $Id$ + * @see KerberosServiceAuthenticationProvider */ public interface KerberosTicketValidator { - public abstract String validateTicket(byte[] token); + /** Validates a Kerberos/SPNEGO ticket. + * @param token Kerbeos/SPNEGO ticket + * @return authenticated kerberos principal + * @throws BadCredentialsException if the ticket is not valid + */ + public String validateTicket(byte[] token) throws BadCredentialsException; } \ No newline at end of file diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/SunJaasKerberosTicketValidator.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/SunJaasKerberosTicketValidator.java index 3988a7f..d7914f2 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/SunJaasKerberosTicketValidator.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/SunJaasKerberosTicketValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,6 +38,10 @@ import org.springframework.security.authentication.BadCredentialsException; import org.springframework.util.Assert; /** + * Implementation of {@link KerberosTicketValidator} which uses the SUN JAAS + * login module, which is included in the SUN JRE, it will not work with an IBM JRE. + * The whole configuration is done in this class, no additional JAAS configuration + * is needed. * * @author Mike Wiesner * @since 1.0 @@ -50,10 +54,9 @@ public class SunJaasKerberosTicketValidator implements KerberosTicketValidator, private Subject serviceSubject; private boolean debug = false; - public void setDebug(boolean debug) { - this.debug = debug; - } - + /* (non-Javadoc) + * @see org.springframework.security.extensions.kerberos.KerberosTicketValidator#validateTicket(byte[]) + */ public String validateTicket(byte[] token) { String username = null; try { @@ -64,14 +67,40 @@ public class SunJaasKerberosTicketValidator implements KerberosTicketValidator, return username; } + /** The service principal of the application. + * For web apps this is HTTP/full-qualified-domain-name@DOMAIN. + * The keytab must contain the key for this principal. + * + * @param servicePrincipal service principal to use + * @see #setKeyTabLocation(Resource) + */ public void setServicePrincipal(String servicePrincipal) { this.servicePrincipal = servicePrincipal; } + /** + * The location of the keytab. You can use the normale Spring Resource + * prefixes like file: or classpath:, but as the + * file is later on read by JAAS, we cannot guarantee that classpath + * works in every environment, esp. not in Java EE application servers. You + * should use file: there. + * + * @param keyTabLocation The location where the keytab resides + */ public void setKeyTabLocation(Resource keyTabLocation) { this.keyTabLocation = keyTabLocation; } + + /** Enables the debug mode of the JAAS Kerberos login module + * @param debug default is false + */ + public void setDebug(boolean debug) { + this.debug = debug; + } + /* (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ @Override public void afterPropertiesSet() throws Exception { Assert.notNull(this.servicePrincipal, "servicePrincipal must be specified"); @@ -86,6 +115,13 @@ public class SunJaasKerberosTicketValidator implements KerberosTicketValidator, this.serviceSubject = lc.getSubject(); } + /** + * This class is needed, because the validation must run with previously generated JAAS subject + * which belongs to the service principal and was loaded out of the keytab during startup. + * + * @author Mike Wiesner + * @since 1.0 + */ private static class KerberosValidateAction implements PrivilegedExceptionAction { byte[] kerberosTicket; @@ -104,6 +140,13 @@ public class SunJaasKerberosTicketValidator implements KerberosTicketValidator, } + /** + * Normally you need a JAAS config file in order to use the JAAS Kerberos Login Module, + * with this class it is not needed and you can have different configurations in one JVM. + * + * @author Mike Wiesner + * @since 1.0 + */ private static class LoginConfig extends Configuration { private String keyTabLocation; private String servicePrincipalName; diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilter.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilter.java index ba56a2c..440e1ce 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilter.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilter.java @@ -30,23 +30,70 @@ import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider; import org.springframework.security.extensions.kerberos.KerberosServiceRequestToken; import org.springframework.web.filter.GenericFilterBean; /** + * Parses the SPNEGO authentication Header, which was generated by the browser + * and creates a {@link KerberosServiceRequestToken} out if it. It will then call the + * {@link AuthenticationManager}. + * + *

A typical Spring Security configuration might look like this:

+ *
+ * <beans xmlns="http://www.springframework.org/schema/beans"
+ *	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://www.springframework.org/schema/security"
+ *	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+ *		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
+ *
+ *	<sec:http entry-point-ref="spnegoEntryPoint">
+ *		<sec:intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_FULLY" />
+ *		<sec:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_PROCESSING_FILTER" />
+ *	</sec:http>
+ *
+ *	<bean id="spnegoEntryPoint" class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />
+ *
+ *	<bean id="spnegoAuthenticationProcessingFilter"
+ *		class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
+ *		<property name="authenticationManager" ref="authenticationManager" />
+ *	</bean>
+ *
+ *	<sec:authentication-manager alias="authenticationManager">
+ *		<sec:authentication-provider ref="kerberosServiceAuthenticationProvider" />
+ *	</sec:authentication-manager>
+ *
+ *	<bean id="kerberosServiceAuthenticationProvider"
+ *		class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
+ *		<property name="ticketValidator">
+ *			<bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
+ *				<property name="servicePrincipal" value="HTTP/web.springsource.com" />
+ *				<property name="keyTabLocation" value="classpath:http-java.keytab" />
+ *			</bean>
+ *		</property>
+ *		<property name="userDetailsService" ref="inMemoryUserDetailsService" />
+ *	</bean>
+ *	
+ *	<bean id="inMemoryUserDetailsService"
+ *		class="org.springframework.security.core.userdetails.memory.InMemoryDaoImpl">
+ *		<property name="userProperties">
+ *			<value>
+ *				mike@SECPOD.DE=notUsed,ROLE_ADMIN
+ *			</value>
+ *		</property>
+ *	</bean>
+ * </beans>
+ * 
* * @author Mike Wiesner * @since 1.0 - * @version $Id: $ + * @version $Id$ + * @see KerberosServiceAuthenticationProvider + * @see SpnegoEntryPoint */ public class SpnegoAuthenticationProcessingFilter extends GenericFilterBean { private AuthenticationManager authenticationManager; - public void setAuthenticationManager(AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } - @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { @@ -66,7 +113,7 @@ public class SpnegoAuthenticationProcessingFilter extends GenericFilterBean { authentication = authenticationManager .authenticate(authenticationRequest); } catch (AuthenticationException e) { - // That shouldn't happen, as it is most likely a wrong configuration on server side + // That shouldn't happen, as it is most likely a wrong configuration on the server side SecurityContextHolder.clearContext(); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.flushBuffer(); @@ -79,5 +126,14 @@ public class SpnegoAuthenticationProcessingFilter extends GenericFilterBean { chain.doFilter(request, response); } + + /** + * The authentication manager for validating the ticket. + * + * @param authenticationManager + */ + public void setAuthenticationManager(AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } } diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoEntryPoint.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoEntryPoint.java index ad320af..ae5f88f 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoEntryPoint.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoEntryPoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,13 +26,18 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; /** + * Sends back a request for a Negotiate Authentication to the browser. * * @author Mike Wiesner * @since 1.0 - * @version $Id: $ + * @version $Id$ + * @see SpnegoAuthenticationProcessingFilter */ public class SpnegoEntryPoint implements AuthenticationEntryPoint { + /* (non-Javadoc) + * @see org.springframework.security.web.AuthenticationEntryPoint#commence(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.AuthenticationException) + */ @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex) throws IOException, ServletException { diff --git a/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProviderTest.java b/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProviderTest.java index dda053c..18643c8 100644 --- a/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProviderTest.java +++ b/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; /** + * Test class for {@link KerberosServiceAuthenticationProvider} * * @author Mike Wiesner * @since 1.0 @@ -45,11 +46,11 @@ public class KerberosServiceAuthenticationProviderTest { private UserDetailsService userDetailsService; // data - private static final byte[] testToken = "TestToken".getBytes(); - private static final String testuser = "Testuser@SPRINGSOURCE.ORG"; - private static final List authorityList = AuthorityUtils.createAuthorityList("ROLE_ADMIN"); - private static final UserDetails userDetails = new User(testuser, "empty", true, true, true,true, authorityList); - private static final KerberosServiceRequestToken input = new KerberosServiceRequestToken(testToken); + private static final byte[] TEST_TOKEN = "TestToken".getBytes(); + private static final String TEST_USER = "Testuser@SPRINGSOURCE.ORG"; + private static final List AUTHORITY_LIST = AuthorityUtils.createAuthorityList("ROLE_ADMIN"); + private static final UserDetails USER_DETAILS = new User(TEST_USER, "empty", true, true, true,true, AUTHORITY_LIST); + private static final KerberosServiceRequestToken INPUT_TOKEN = new KerberosServiceRequestToken(TEST_TOKEN); @Before public void before() { @@ -64,34 +65,34 @@ public class KerberosServiceAuthenticationProviderTest { @Test public void testEverythingWorks() throws Exception { // stubbing - when(ticketValidator.validateTicket(testToken)).thenReturn(testuser); - when(userDetailsService.loadUserByUsername(testuser)).thenReturn(userDetails); + when(ticketValidator.validateTicket(TEST_TOKEN)).thenReturn(TEST_USER); + when(userDetailsService.loadUserByUsername(TEST_USER)).thenReturn(USER_DETAILS); // testing - Authentication output = provider.authenticate(input); + Authentication output = provider.authenticate(INPUT_TOKEN); assertNotNull(output); - assertEquals(testuser, output.getName()); - assertEquals(authorityList, output.getAuthorities()); - assertEquals(userDetails, output.getPrincipal()); + assertEquals(TEST_USER, output.getName()); + assertEquals(AUTHORITY_LIST, output.getAuthorities()); + assertEquals(USER_DETAILS, output.getPrincipal()); } @Test(expected=UsernameNotFoundException.class) public void testUsernameNotFound() throws Exception { // stubbing - when(ticketValidator.validateTicket(testToken)).thenReturn(testuser); - when(userDetailsService.loadUserByUsername(testuser)).thenThrow(new UsernameNotFoundException("")); + when(ticketValidator.validateTicket(TEST_TOKEN)).thenReturn(TEST_USER); + when(userDetailsService.loadUserByUsername(TEST_USER)).thenThrow(new UsernameNotFoundException("")); // testing - provider.authenticate(input); + provider.authenticate(INPUT_TOKEN); } @Test(expected=BadCredentialsException.class) public void testTicketValidationWrong() throws Exception { // stubbing - when(ticketValidator.validateTicket(testToken)).thenThrow(new BadCredentialsException("")); + when(ticketValidator.validateTicket(TEST_TOKEN)).thenThrow(new BadCredentialsException("")); // testing - provider.authenticate(input); + provider.authenticate(INPUT_TOKEN); } } diff --git a/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java b/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java index 6d9107e..8efbaa2 100644 --- a/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java +++ b/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.extensions.kerberos.KerberosServiceRequestToken; /** + * Test class for {@link SpnegoAuthenticationProcessingFilter} * * @author Mike Wiesner * @since 1.0 @@ -42,17 +43,21 @@ import org.springframework.security.extensions.kerberos.KerberosServiceRequestTo */ public class SpnegoAuthenticationProcessingFilterTest { + + private SpnegoAuthenticationProcessingFilter filter; private AuthenticationManager authenticationManager; private HttpServletRequest request; private HttpServletResponse response; private FilterChain chain; - + // data - private static final byte[] testToken = "TestToken".getBytes(); - private static final String testTokenBase64 = "VGVzdFRva2Vu"; - private static final Authentication authentication = new KerberosServiceRequestToken("test", - AuthorityUtils.createAuthorityList("ROLE_ADMIN"), testToken); + private static final byte[] TEST_TOKEN = "TestToken".getBytes(); + private static final String TEST_TOKEN_BASE64 = "VGVzdFRva2Vu"; + private static final Authentication AUTHENTICATION = new KerberosServiceRequestToken("test", + AuthorityUtils.createAuthorityList("ROLE_ADMIN"), TEST_TOKEN); + private static final String HEADER = "Authorization"; + private static final String TOKEN_PREFIX = "Negotiate "; @Before @@ -69,13 +74,13 @@ public class SpnegoAuthenticationProcessingFilterTest { @Test public void testEverythingWorks() throws Exception { // stubbing - when(request.getHeader("Authorization")).thenReturn("Negotiate "+testTokenBase64); - when(authenticationManager.authenticate(new KerberosServiceRequestToken(testToken))).thenReturn(authentication); + when(request.getHeader(HEADER)).thenReturn(TOKEN_PREFIX+TEST_TOKEN_BASE64); + when(authenticationManager.authenticate(new KerberosServiceRequestToken(TEST_TOKEN))).thenReturn(AUTHENTICATION); // testing filter.doFilter(request, response, chain); verify(chain).doFilter(request, response); - assertEquals(authentication, SecurityContextHolder.getContext().getAuthentication()); + assertEquals(AUTHENTICATION, SecurityContextHolder.getContext().getAuthentication()); } @Test @@ -91,7 +96,7 @@ public class SpnegoAuthenticationProcessingFilterTest { @Test public void testAuthenticationFails() throws Exception { // stubbing - when(request.getHeader("Authorization")).thenReturn("Negotiate "+testTokenBase64); + when(request.getHeader(HEADER)).thenReturn(TOKEN_PREFIX+TEST_TOKEN_BASE64); when(authenticationManager.authenticate(any(Authentication.class))).thenThrow(new BadCredentialsException("")); // testing diff --git a/spring-security-kerberos-sample/src/main/java/org/springframework/security/extensions/kerberos/sample/DummyUserDetailsService.java b/spring-security-kerberos-sample/src/main/java/org/springframework/security/extensions/kerberos/sample/DummyUserDetailsService.java index 7bbb874..1ae6296 100644 --- a/spring-security-kerberos-sample/src/main/java/org/springframework/security/extensions/kerberos/sample/DummyUserDetailsService.java +++ b/spring-security-kerberos-sample/src/main/java/org/springframework/security/extensions/kerberos/sample/DummyUserDetailsService.java @@ -24,6 +24,10 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; /** + * Implementation of {@link UserDetailsService} which just returns the a new {@link User} + * with username equals the provided username and ROLE_USER as granted authority. + * + * Useful if you don't know the exact username and just want to see if Kerberos works * * @author Mike Wiesner * @since 1.0 @@ -32,6 +36,9 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; public class DummyUserDetailsService implements UserDetailsService { + /* (non-Javadoc) + * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String) + */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { return new User(username, "notUsed", true, true,true,true, AuthorityUtils.createAuthorityList("ROLE_USER"));