Add support for Kerberos (as well as Negotiate) authentication.

Include support for WWW-Authenticate response.
Include support for decrypt.
(Dispose gss context and encrypt still to do)
This commit is contained in:
Jeremy.Stone
2014-04-07 11:28:13 +01:00
parent cd892788a5
commit 3fa6b153fe
9 changed files with 352 additions and 75 deletions

View File

@@ -17,9 +17,9 @@ configure(allprojects) {
sourceCompatibility=1.6
targetCompatibility=1.6
ext.junitVersion = '4.10'
ext.junitVersion = '4.11'
ext.springSecurityVersion = '3.1.4.RELEASE'
ext.springVersion = '3.2.2.RELEASE'
ext.springVersion = '3.2.3.RELEASE'
[compileJava, compileTestJava]*.options*.compilerArgs = ['-Xlint:none']

View File

@@ -26,6 +26,7 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.extensions.kerberos.KerberosTicketValidator.KerberosTicketValidation;
import org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter;
import org.springframework.util.Assert;
@@ -82,15 +83,16 @@ public class KerberosServiceAuthenticationProvider implements
KerberosServiceRequestToken auth = (KerberosServiceRequestToken) authentication;
byte[] token = auth.getToken();
LOG.debug("Try to validate Kerberos Token");
String username = this.ticketValidator.validateTicket(token);
LOG.debug("Succesfully validated " + username);
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
KerberosTicketValidation ticketValidation = this.ticketValidator.validateTicket(token);
LOG.debug("Succesfully validated " + ticketValidation.username());
UserDetails userDetails = this.userDetailsService.loadUserByUsername(ticketValidation.username());
userDetailsChecker.check(userDetails);
additionalAuthenticationChecks(userDetails, auth);
KerberosServiceRequestToken responseAuth = new KerberosServiceRequestToken(userDetails, userDetails.getAuthorities(), token);
KerberosServiceRequestToken responseAuth = new KerberosServiceRequestToken(
userDetails, ticketValidation,
userDetails.getAuthorities(), token);
responseAuth.setDetails(authentication.getDetails());
return responseAuth;
return responseAuth;
}

View File

@@ -16,22 +16,32 @@
package org.springframework.security.extensions.kerberos;
import java.io.UnsupportedEncodingException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.Collection;
import javax.security.auth.Subject;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.MessageProp;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.security.extensions.kerberos.KerberosTicketValidator.KerberosTicketValidation;
import org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter;
/**
* Holds the Kerberos/SPNEGO token for requesting a kerberized service
* and is also the output of <code>KerberosServiceAuthenticationProvider</code>.<br>
* Holds the Kerberos/SPNEGO token for requesting a kerberized service and is
* also the output of <code>KerberosServiceAuthenticationProvider</code>.<br>
* Will mostly be created in <code>SpnegoAuthenticationProcessingFilter</code>
* and authenticated in <code>KerberosServiceAuthenticationProvider</code>.
*
* This token cannot be re-authenticated, as you will get a Kerberos Reply error.
*
*
* This token cannot be re-authenticated, as you will get a Kerberos Reply
* error.
*
* @author Mike Wiesner
* @since 1.0
* @version $Id$
@@ -42,19 +52,27 @@ import org.springframework.security.extensions.kerberos.web.SpnegoAuthentication
public class KerberosServiceRequestToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = 395488921064775014L;
private final byte[] token;
private final Object principal;
private final KerberosTicketValidation ticketValidation;
/** Creates an authenticated token, normally used as an output of an authentication provider.
* @param principal the user principal (mostly of instance <code>UserDetails</code>
* @param ticketValidation result of ticket validation
* @param authorities the authorities which are granted to the user
* @param token the Kerberos/SPNEGO token
* @see UserDetails
*/
public KerberosServiceRequestToken(Object principal, Collection<? extends GrantedAuthority> authorities, byte[] token) {
public KerberosServiceRequestToken(Object principal,
KerberosTicketValidation ticketValidation,
Collection<? extends GrantedAuthority> authorities, byte[] token) {
super(authorities);
this.token = token;
this.principal = principal;
this.ticketValidation = ticketValidation;
super.setAuthenticated(true);
}
@@ -68,6 +86,7 @@ public class KerberosServiceRequestToken extends AbstractAuthenticationToken {
public KerberosServiceRequestToken(byte[] token) {
super(null);
this.token = token;
this.ticketValidation = null;
this.principal = null;
}
@@ -113,10 +132,73 @@ public class KerberosServiceRequestToken extends AbstractAuthenticationToken {
return this.principal;
}
/** Returns the Kerberos token
/**
* Returns the Kerberos token
*/
public byte[] getToken() {
return this.token;
}
/**
* Gets the ticket validation
*
* @return the ticket validation (which will be null if the token is
* unauthenticated)
*/
public KerberosTicketValidation getTicketValidation() {
return ticketValidation;
}
/**
* Determines whether an authenticated token has a response token
*
* @return whether a response token is available
*/
public boolean hasResponseToken() {
return ticketValidation != null
&& ticketValidation.responseToken() != null;
}
/**
* Gets the (Base64) encoded response token assuming one is available.
*
* @return encoded response token
*/
public String getEncodedResponseToken() {
if (!hasResponseToken())
throw new IllegalStateException(
"Unauthenticated or no response token");
try {
return new String(Base64.encode(ticketValidation.responseToken()),
"UTF-8");
}
catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Unable to encode response token",
e);
}
}
/**
* Unwraps an encrypted message using the gss context
*
* @param data
* @param offset
* @param length
* @return the decrypted message
* @throws PrivilegedActionException
*/
public byte[] decrypt(final byte[] data, final int offset, final int length)
throws PrivilegedActionException {
return Subject.doAs(getTicketValidation().subject(),
new PrivilegedExceptionAction<byte[]>() {
public byte[] run() throws Exception {
final GSSContext context = getTicketValidation()
.getGssContext();
return context.unwrap(data, offset, length,
new MessageProp(true));
}
});
}
}

View File

@@ -16,12 +16,19 @@
package org.springframework.security.extensions.kerberos;
import java.util.HashSet;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosPrincipal;
import org.ietf.jgss.GSSContext;
import org.springframework.security.authentication.BadCredentialsException;
/**
* Implementations of this interface are used in
* {@link KerberosServiceAuthenticationProvider} to validate a Kerberos/SPNEGO Ticket.
*
* {@link KerberosServiceAuthenticationProvider} to validate a Kerberos/SPNEGO
* Ticket.
*
* @author Mike Wiesner
* @since 1.0
* @version $Id$
@@ -29,11 +36,55 @@ import org.springframework.security.authentication.BadCredentialsException;
*/
public interface KerberosTicketValidator {
/** Validates a Kerberos/SPNEGO ticket.
/**
* 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;
public KerberosTicketValidation validateTicket(byte[] token)
throws BadCredentialsException;
}
/**
* Result of ticket validation
*
* @author Jeremy.Stone
*/
public static class KerberosTicketValidation {
private final String username;
private final byte[] responseToken;
private final GSSContext gssContext;
private final String servicePrincipal;
KerberosTicketValidation(String username, String servicePrincipal,
byte[] responseToken, GSSContext gssContext) {
this.username = username;
this.servicePrincipal = servicePrincipal;
this.responseToken = responseToken;
this.gssContext = gssContext;
}
public String username() {
return username;
}
public byte[] responseToken() {
return responseToken;
}
public GSSContext getGssContext() {
return gssContext;
}
public Subject subject() {
final HashSet<KerberosPrincipal> princs = new HashSet<KerberosPrincipal>();
princs.add(new KerberosPrincipal(servicePrincipal));
return new Subject(false, princs, new HashSet<Object>(),
new HashSet<Object>());
}
}
}

View File

@@ -61,14 +61,15 @@ public class SunJaasKerberosTicketValidator implements KerberosTicketValidator,
/* (non-Javadoc)
* @see org.springframework.security.extensions.kerberos.KerberosTicketValidator#validateTicket(byte[])
*/
public String validateTicket(byte[] token) {
String username = null;
public KerberosTicketValidation validateTicket(byte[] token) {
try {
username = Subject.doAs(this.serviceSubject, new KerberosValidateAction(token));
} catch (PrivilegedActionException e) {
throw new BadCredentialsException("Kerberos validation not succesfull", e);
return Subject.doAs(this.serviceSubject,
new KerberosValidateAction(token));
}
catch (PrivilegedActionException e) {
throw new BadCredentialsException(
"Kerberos validation not succesful", e);
}
return username;
}
/** The service principal of the application.
@@ -139,21 +140,26 @@ public class SunJaasKerberosTicketValidator implements KerberosTicketValidator,
* @author Mike Wiesner
* @since 1.0
*/
private static class KerberosValidateAction implements PrivilegedExceptionAction<String> {
private class KerberosValidateAction implements PrivilegedExceptionAction<KerberosTicketValidation> {
byte[] kerberosTicket;
public KerberosValidateAction(byte[] kerberosTicket) {
this.kerberosTicket = kerberosTicket;
}
public String run() throws Exception {
GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null);
context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length);
@Override
public KerberosTicketValidation run() throws Exception {
GSSContext context = GSSManager.getInstance().createContext(
(GSSCredential) null);
byte[] responseToken = context.acceptSecContext(kerberosTicket, 0,
kerberosTicket.length);
String user = context.getSrcName().toString();
context.dispose();
return user;
}
// context.dispose();
return new KerberosTicketValidation(user, servicePrincipal,
responseToken, context);
}
}
/**

View File

@@ -0,0 +1,66 @@
package org.springframework.security.extensions.kerberos.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.extensions.kerberos.KerberosServiceRequestToken;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
/**
* Adds a WWW-Authenticate (or other) header to the response following
* successful authentication.
*
* @author Jeremy.Stone
*/
public class ResponseHeaderSettingKerberosAuthenticationSuccessHandler
implements AuthenticationSuccessHandler {
private static final String NEGOTIATE_PREFIX = "Negotiate ";
private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
private String headerName = WWW_AUTHENTICATE;
private String headerPrefix = NEGOTIATE_PREFIX;
/**
* Sets the name of the header to set. By default this is
* {@value #WWW_AUTHENTICATE}.
*
* @param a_headerName
*/
public void setHeaderName(String a_headerName) {
headerName = a_headerName;
}
/**
* Sets the value of the prefix for the encoded response token value. By
* default this is {@value #NEGOTIATE_PREFIX}.
*
* @param a_headerPrefix
*/
public void setHeaderPrefix(String a_headerPrefix) {
headerPrefix = a_headerPrefix;
}
/**
* @see org.springframework.security.web.authentication.AuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse,
* org.springframework.security.core.Authentication)
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
KerberosServiceRequestToken auth = (KerberosServiceRequestToken) authentication;
if (auth.hasResponseToken()) {
response.addHeader(headerName,
headerPrefix + auth.getEncodedResponseToken());
}
}
}

View File

@@ -36,7 +36,6 @@ import org.springframework.security.extensions.kerberos.KerberosServiceAuthentic
import org.springframework.security.extensions.kerberos.KerberosServiceRequestToken;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@@ -142,11 +141,14 @@ public class SpnegoAuthenticationProcessingFilter extends GenericFilterBean {
String header = request.getHeader("Authorization");
if ((header != null) && header.startsWith("Negotiate ")) {
if (header != null
&& (header.startsWith("Negotiate ") || header
.startsWith("Kerberos "))) {
if (logger.isDebugEnabled()) {
logger.debug("Received Negotiate Header for request " + request.getRequestURL() + ": " + header);
}
byte[] base64Token = header.substring(10).getBytes("UTF-8");
byte[] base64Token = header.substring(header.indexOf(" ") + 1)
.getBytes("UTF-8");
byte[] kerberosTicket = Base64.decode(base64Token);
KerberosServiceRequestToken authenticationRequest = new KerberosServiceRequestToken(kerberosTicket);
authenticationRequest.setDetails(authenticationDetailsSource.buildDetails(request));

View File

@@ -35,6 +35,7 @@ import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.extensions.kerberos.KerberosTicketValidator.KerberosTicketValidation;
/**
* Test class for {@link KerberosServiceAuthenticationProvider}
@@ -51,7 +52,11 @@ public class KerberosServiceAuthenticationProviderTest {
// data
private static final byte[] TEST_TOKEN = "TestToken".getBytes();
private static final byte[] RESPONSE_TOKEN = "ResponseToken".getBytes();
private static final String TEST_USER = "Testuser@SPRINGSOURCE.ORG";
private static final KerberosTicketValidation TICKET_VALIDATION = new KerberosTicketValidation(TEST_USER, "XXX", RESPONSE_TOKEN, null);
private static final List<GrantedAuthority> 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);
@@ -111,7 +116,7 @@ public class KerberosServiceAuthenticationProviderTest {
@Test(expected=UsernameNotFoundException.class)
public void testUsernameNotFound() throws Exception {
// stubbing
when(ticketValidator.validateTicket(TEST_TOKEN)).thenReturn(TEST_USER);
when(ticketValidator.validateTicket(TEST_TOKEN)).thenReturn(TICKET_VALIDATION);
when(userDetailsService.loadUserByUsername(TEST_USER)).thenThrow(new UsernameNotFoundException(""));
// testing
@@ -130,7 +135,7 @@ public class KerberosServiceAuthenticationProviderTest {
private Authentication callProviderAndReturnUser(UserDetails userDetails, Authentication inputToken) {
// stubbing
when(ticketValidator.validateTicket(TEST_TOKEN)).thenReturn(TEST_USER);
when(ticketValidator.validateTicket(TEST_TOKEN)).thenReturn(TICKET_VALIDATION);
when(userDetailsService.loadUserByUsername(TEST_USER)).thenReturn(userDetails);
// testing

View File

@@ -15,8 +15,13 @@
*/
package org.springframework.security.extensions.kerberos.web;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
@@ -39,6 +44,7 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.extensions.kerberos.KerberosServiceRequestToken;
import org.springframework.security.extensions.kerberos.KerberosTicketValidator.KerberosTicketValidation;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
@@ -53,22 +59,40 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS
public class SpnegoAuthenticationProcessingFilterTest {
private SpnegoAuthenticationProcessingFilter filter;
private AuthenticationManager authenticationManager;
private HttpServletRequest request;
private HttpServletResponse response;
private FilterChain chain;
private AuthenticationSuccessHandler successHandler;
private AuthenticationFailureHandler failureHandler;
private WebAuthenticationDetailsSource detailsSource;
// data
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 KerberosTicketValidation UNUSED_TICKET_VALIDATION = mock(KerberosTicketValidation.class);
private static final Authentication AUTHENTICATION = new KerberosServiceRequestToken(
"test", UNUSED_TICKET_VALIDATION, AuthorityUtils.createAuthorityList("ROLE_ADMIN"),
TEST_TOKEN);
private static final String HEADER = "Authorization";
private static final String TOKEN_PREFIX = "Negotiate ";
private static final BadCredentialsException BCE = new BadCredentialsException("");
private static final String TOKEN_PREFIX_NEG = "Negotiate ";
private static final String TOKEN_PREFIX_KERB = "Kerberos ";
private static final BadCredentialsException BCE = new BadCredentialsException(
"");
@Before
public void before() throws Exception {
@@ -85,29 +109,50 @@ public class SpnegoAuthenticationProcessingFilterTest {
@Test
public void testEverythingWorks() throws Exception {
everythingWorks();
everythingWorks(TOKEN_PREFIX_NEG);
}
@Test
public void testEverythingWorks_Kerberos() throws Exception {
everythingWorks(TOKEN_PREFIX_KERB);
}
@Test
public void testEverythingWorksWithHandlers() throws Exception {
everythingWorksWithHandlers(TOKEN_PREFIX_NEG);
}
@Test
public void testEverythingWorksWithHandlers_Kerberos() throws Exception {
everythingWorksWithHandlers(TOKEN_PREFIX_KERB);
}
private void everythingWorksWithHandlers(String tokenPrefix) throws Exception {
createHandler();
everythingWorks();
verify(successHandler).onAuthenticationSuccess(request, response, AUTHENTICATION);
verify(failureHandler, never()).onAuthenticationFailure(any(HttpServletRequest.class), any(HttpServletResponse.class),
everythingWorks(tokenPrefix);
verify(successHandler).onAuthenticationSuccess(request, response,
AUTHENTICATION);
verify(failureHandler, never()).onAuthenticationFailure(
any(HttpServletRequest.class), any(HttpServletResponse.class),
any(AuthenticationException.class));
}
private void everythingWorks() throws IOException, ServletException {
private void everythingWorks(String tokenPrefix) throws IOException,
ServletException {
// stubbing
when(request.getHeader(HEADER)).thenReturn(TOKEN_PREFIX + TEST_TOKEN_BASE64);
KerberosServiceRequestToken requestToken = new KerberosServiceRequestToken(TEST_TOKEN);
when(request.getHeader(HEADER)).thenReturn(
tokenPrefix + TEST_TOKEN_BASE64);
KerberosServiceRequestToken requestToken = new KerberosServiceRequestToken(
TEST_TOKEN);
requestToken.setDetails(detailsSource.buildDetails(request));
when(authenticationManager.authenticate(requestToken)).thenReturn(AUTHENTICATION);
when(authenticationManager.authenticate(requestToken)).thenReturn(
AUTHENTICATION);
// testing
filter.doFilter(request, response, chain);
verify(chain).doFilter(request, response);
assertEquals(AUTHENTICATION, SecurityContextHolder.getContext().getAuthentication());
assertEquals(AUTHENTICATION, SecurityContextHolder.getContext()
.getAuthentication());
}
@Test
@@ -115,16 +160,19 @@ public class SpnegoAuthenticationProcessingFilterTest {
filter.doFilter(request, response, chain);
// If the header is not present, the filter is not allowed to call
// authenticate()
verify(authenticationManager, never()).authenticate(any(Authentication.class));
verify(authenticationManager, never()).authenticate(
any(Authentication.class));
// chain should go on
verify(chain).doFilter(request, response);
assertEquals(null, SecurityContextHolder.getContext().getAuthentication());
assertEquals(null, SecurityContextHolder.getContext()
.getAuthentication());
}
@Test
public void testAuthenticationFails() throws Exception {
authenticationFails();
verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
verify(response)
.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
@Test
@@ -132,7 +180,8 @@ public class SpnegoAuthenticationProcessingFilterTest {
createHandler();
authenticationFails();
verify(failureHandler).onAuthenticationFailure(request, response, BCE);
verify(successHandler, never()).onAuthenticationSuccess(any(HttpServletRequest.class), any(HttpServletResponse.class),
verify(successHandler, never()).onAuthenticationSuccess(
any(HttpServletRequest.class), any(HttpServletResponse.class),
any(Authentication.class));
verify(response, never()).setStatus(anyInt());
}
@@ -140,25 +189,32 @@ public class SpnegoAuthenticationProcessingFilterTest {
@Test
public void testAlreadyAuthenticated() throws Exception {
try {
Authentication existingAuth = new UsernamePasswordAuthenticationToken("mike", "mike",
Authentication existingAuth = new UsernamePasswordAuthenticationToken(
"mike", "mike",
AuthorityUtils.createAuthorityList("ROLE_TEST"));
SecurityContextHolder.getContext().setAuthentication(existingAuth);
when(request.getHeader(HEADER)).thenReturn(TOKEN_PREFIX + TEST_TOKEN_BASE64);
when(request.getHeader(HEADER)).thenReturn(
TOKEN_PREFIX_NEG + TEST_TOKEN_BASE64);
filter.doFilter(request, response, chain);
verify(authenticationManager, never()).authenticate(any(Authentication.class));
} finally {
verify(authenticationManager, never()).authenticate(
any(Authentication.class));
}
finally {
SecurityContextHolder.clearContext();
}
}
@Test
public void testAlreadyAuthenticatedWithNotAuthenticatedToken() throws Exception {
public void testAlreadyAuthenticatedWithNotAuthenticatedToken()
throws Exception {
try {
// this token is not authenticated yet!
Authentication existingAuth = new UsernamePasswordAuthenticationToken("mike", "mike");
Authentication existingAuth = new UsernamePasswordAuthenticationToken(
"mike", "mike");
SecurityContextHolder.getContext().setAuthentication(existingAuth);
everythingWorks();
} finally {
everythingWorks(TOKEN_PREFIX_NEG);
}
finally {
SecurityContextHolder.clearContext();
}
}
@@ -166,38 +222,45 @@ public class SpnegoAuthenticationProcessingFilterTest {
@Test
public void testAlreadyAuthenticatedWithAnonymousToken() throws Exception {
try {
Authentication existingAuth = new AnonymousAuthenticationToken("test", "mike",
Authentication existingAuth = new AnonymousAuthenticationToken(
"test", "mike",
AuthorityUtils.createAuthorityList("ROLE_TEST"));
SecurityContextHolder.getContext().setAuthentication(existingAuth);
everythingWorks();
} finally {
everythingWorks(TOKEN_PREFIX_NEG);
}
finally {
SecurityContextHolder.clearContext();
}
}
@Test
public void testAlreadyAuthenticatedNotActive() throws Exception {
try {
Authentication existingAuth = new UsernamePasswordAuthenticationToken("mike", "mike",
Authentication existingAuth = new UsernamePasswordAuthenticationToken(
"mike", "mike",
AuthorityUtils.createAuthorityList("ROLE_TEST"));
SecurityContextHolder.getContext().setAuthentication(existingAuth);
filter.setSkipIfAlreadyAuthenticated(false);
everythingWorks();
} finally {
everythingWorks(TOKEN_PREFIX_NEG);
}
finally {
SecurityContextHolder.clearContext();
}
}
private void authenticationFails() throws IOException, ServletException {
// stubbing
when(request.getHeader(HEADER)).thenReturn(TOKEN_PREFIX + TEST_TOKEN_BASE64);
when(authenticationManager.authenticate(any(Authentication.class))).thenThrow(BCE);
when(request.getHeader(HEADER)).thenReturn(
TOKEN_PREFIX_NEG + TEST_TOKEN_BASE64);
when(authenticationManager.authenticate(any(Authentication.class)))
.thenThrow(BCE);
// testing
filter.doFilter(request, response, chain);
// chain should stop here and it should send back a 500
// future version should call some error handler
verify(chain, never()).doFilter(any(ServletRequest.class), any(ServletResponse.class));
verify(chain, never()).doFilter(any(ServletRequest.class),
any(ServletResponse.class));
}
private void createHandler() {