mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	SEC-234: Allow pluggable AuthenticationDetailsSource strategy interface.
This commit is contained in:
		
							parent
							
								
									b1becf9277
								
							
						
					
					
						commit
						a47a342ce6
					
				| @ -19,7 +19,8 @@ import org.acegisecurity.Authentication; | ||||
| 
 | ||||
| import org.acegisecurity.context.SecurityContextHolder; | ||||
| 
 | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSource; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSourceImpl; | ||||
| 
 | ||||
| import org.acegisecurity.userdetails.memory.UserAttribute; | ||||
| 
 | ||||
| @ -61,6 +62,7 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { | ||||
| 
 | ||||
|     //~ Instance fields ======================================================== | ||||
| 
 | ||||
|     private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); | ||||
|     private String key; | ||||
|     private UserAttribute userAttribute; | ||||
|     private boolean removeAfterRequest = true; | ||||
| @ -96,8 +98,8 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { | ||||
| 
 | ||||
|         AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key, | ||||
|                 userAttribute.getPassword(), userAttribute.getAuthorities()); | ||||
|         auth.setDetails(new WebAuthenticationDetails( | ||||
|                 (HttpServletRequest) request, false)); | ||||
|         auth.setDetails(authenticationDetailsSource.buildDetails( | ||||
|                 (HttpServletRequest) request)); | ||||
| 
 | ||||
|         return auth; | ||||
|     } | ||||
| @ -167,6 +169,13 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { | ||||
|         return removeAfterRequest; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthenticationDetailsSource( | ||||
|         AuthenticationDetailsSource authenticationDetailsSource) { | ||||
|         Assert.notNull(authenticationDetailsSource, | ||||
|             "AuthenticationDetailsSource required"); | ||||
|         this.authenticationDetailsSource = authenticationDetailsSource; | ||||
|     } | ||||
| 
 | ||||
|     public void setKey(String key) { | ||||
|         this.key = key; | ||||
|     } | ||||
|  | ||||
| @ -143,6 +143,7 @@ public abstract class AbstractProcessingFilter implements Filter, | ||||
|     //~ Instance fields ======================================================== | ||||
| 
 | ||||
|     protected ApplicationEventPublisher eventPublisher; | ||||
|     protected AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); | ||||
|     private AuthenticationManager authenticationManager; | ||||
|     protected final Log logger = LogFactory.getLog(this.getClass()); | ||||
|     protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); | ||||
| @ -371,6 +372,13 @@ public abstract class AbstractProcessingFilter implements Filter, | ||||
|         this.eventPublisher = eventPublisher; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthenticationDetailsSource( | ||||
|         AuthenticationDetailsSource authenticationDetailsSource) { | ||||
|         Assert.notNull(authenticationDetailsSource, | ||||
|             "AuthenticationDetailsSource required"); | ||||
|         this.authenticationDetailsSource = authenticationDetailsSource; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthenticationFailureUrl(String authenticationFailureUrl) { | ||||
|         this.authenticationFailureUrl = authenticationFailureUrl; | ||||
|     } | ||||
|  | ||||
| @ -0,0 +1,41 @@ | ||||
| /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package org.acegisecurity.ui; | ||||
| 
 | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Provides a {@link org.acegisecurity.Authentication#getDetails()} object for | ||||
|  * a given web request. | ||||
|  * | ||||
|  * @author Ben Alex | ||||
|  * @version $Id$ | ||||
|  */ | ||||
| public interface AuthenticationDetailsSource { | ||||
|     //~ Methods ================================================================ | ||||
| 
 | ||||
|     /** | ||||
|      * Called by a class when it wishes a new authentication details instance | ||||
|      * to be created. | ||||
|      * | ||||
|      * @param request the request object, which may be used by the | ||||
|      *        authentication details object | ||||
|      * | ||||
|      * @return a fully-configured authentication details instance | ||||
|      */ | ||||
|     public Object buildDetails(HttpServletRequest request); | ||||
| } | ||||
| @ -0,0 +1,69 @@ | ||||
| /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package org.acegisecurity.ui; | ||||
| 
 | ||||
| import org.springframework.util.Assert; | ||||
| import org.springframework.util.ReflectionUtils; | ||||
| 
 | ||||
| import java.lang.reflect.Constructor; | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| 
 | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Base implementation of {@link AuthenticationDetailsSource}. | ||||
|  *  | ||||
|  * <P> | ||||
|  * By default will create an instance of <code>WebAuthenticationDetails</code>. | ||||
|  * Any object that accepts a <code>HttpServletRequest</code> as its sole | ||||
|  * constructor can be used instead of this default. | ||||
|  * </p> | ||||
|  * | ||||
|  * @author Ben Alex | ||||
|  * @version $Id$ | ||||
|  */ | ||||
| public class AuthenticationDetailsSourceImpl | ||||
|     implements AuthenticationDetailsSource { | ||||
|     //~ Instance fields ======================================================== | ||||
| 
 | ||||
|     private Class clazz = WebAuthenticationDetails.class; | ||||
| 
 | ||||
|     //~ Methods ================================================================ | ||||
| 
 | ||||
|     public Object buildDetails(HttpServletRequest request) { | ||||
|         try { | ||||
|             Constructor constructor = clazz.getConstructor(new Class[] {HttpServletRequest.class}); | ||||
| 
 | ||||
|             return constructor.newInstance(new Object[] {request}); | ||||
|         } catch (NoSuchMethodException ex) { | ||||
|             ReflectionUtils.handleReflectionException(ex); | ||||
|         } catch (InvocationTargetException ex) { | ||||
|             ReflectionUtils.handleReflectionException(ex); | ||||
|         } catch (InstantiationException ex) { | ||||
|             ReflectionUtils.handleReflectionException(ex); | ||||
|         } catch (IllegalAccessException ex) { | ||||
|             ReflectionUtils.handleReflectionException(ex); | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     public void setClazz(Class clazz) { | ||||
|         Assert.notNull(clazz, "Class required"); | ||||
|         this.clazz = clazz; | ||||
|     } | ||||
| } | ||||
| @ -52,15 +52,8 @@ public class WebAuthenticationDetails implements SessionIdentifierAware, | ||||
|      */ | ||||
|     public WebAuthenticationDetails(HttpServletRequest request) { | ||||
|         this.remoteAddress = request.getRemoteAddr(); | ||||
|         this.sessionId = request.getSession(true).getId(); | ||||
|         doPopulateAdditionalInformation(request); | ||||
|     } | ||||
| 
 | ||||
|     public WebAuthenticationDetails(HttpServletRequest request, | ||||
|         boolean forceSessionCreation) { | ||||
|         this.remoteAddress = request.getRemoteAddr(); | ||||
| 
 | ||||
|         HttpSession session = request.getSession(forceSessionCreation); | ||||
|         HttpSession session = request.getSession(false); | ||||
|         this.sessionId = (session != null) ? session.getId() : null; | ||||
| 
 | ||||
|         doPopulateAdditionalInformation(request); | ||||
|  | ||||
| @ -23,8 +23,9 @@ import org.acegisecurity.context.SecurityContextHolder; | ||||
| 
 | ||||
| import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; | ||||
| 
 | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSource; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSourceImpl; | ||||
| import org.acegisecurity.ui.AuthenticationEntryPoint; | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| 
 | ||||
| import org.apache.commons.codec.binary.Base64; | ||||
| import org.apache.commons.logging.Log; | ||||
| @ -115,9 +116,15 @@ public class BasicProcessingFilter implements Filter, InitializingBean { | ||||
|     private AuthenticationEntryPoint authenticationEntryPoint; | ||||
|     private AuthenticationManager authenticationManager; | ||||
|     private boolean ignoreFailure = false; | ||||
|     private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); | ||||
| 
 | ||||
|     //~ Methods ================================================================ | ||||
| 
 | ||||
|     public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { | ||||
|     	Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); | ||||
| 		this.authenticationDetailsSource = authenticationDetailsSource; | ||||
| 	} | ||||
| 
 | ||||
|     public void afterPropertiesSet() throws Exception { | ||||
|         Assert.notNull(this.authenticationManager, | ||||
|             "An AuthenticationManager is required"); | ||||
| @ -168,8 +175,7 @@ public class BasicProcessingFilter implements Filter, InitializingBean { | ||||
|                 || !existingAuth.isAuthenticated()) { | ||||
|                 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, | ||||
|                         password); | ||||
|                 authRequest.setDetails(new WebAuthenticationDetails( | ||||
|                         httpRequest, false)); | ||||
|                 authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); | ||||
| 
 | ||||
|                 Authentication authResult; | ||||
| 
 | ||||
|  | ||||
| @ -19,7 +19,6 @@ import org.acegisecurity.Authentication; | ||||
| import org.acegisecurity.AuthenticationException; | ||||
| import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; | ||||
| import org.acegisecurity.ui.AbstractProcessingFilter; | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| 
 | ||||
| import javax.servlet.FilterConfig; | ||||
| import javax.servlet.ServletException; | ||||
| @ -105,7 +104,7 @@ public class CasProcessingFilter extends AbstractProcessingFilter { | ||||
|         UsernamePasswordAuthenticationToken authRequest = | ||||
|                 new UsernamePasswordAuthenticationToken(username, password); | ||||
| 
 | ||||
|         authRequest.setDetails(new WebAuthenticationDetails(request, false)); | ||||
|         authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); | ||||
| 
 | ||||
|         return this.getAuthenticationManager().authenticate(authRequest); | ||||
|     } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* Copyright 2004, 2005 Acegi Technology Pty Limited | ||||
| /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -15,7 +15,42 @@ | ||||
| 
 | ||||
| package org.acegisecurity.ui.digestauth; | ||||
| 
 | ||||
| import org.acegisecurity.AcegiMessageSource; | ||||
| import org.acegisecurity.AuthenticationException; | ||||
| import org.acegisecurity.AuthenticationServiceException; | ||||
| import org.acegisecurity.BadCredentialsException; | ||||
| 
 | ||||
| import org.acegisecurity.context.SecurityContextHolder; | ||||
| 
 | ||||
| import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; | ||||
| import org.acegisecurity.providers.dao.UserCache; | ||||
| import org.acegisecurity.providers.dao.cache.NullUserCache; | ||||
| 
 | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSource; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSourceImpl; | ||||
| 
 | ||||
| import org.acegisecurity.userdetails.UserDetails; | ||||
| import org.acegisecurity.userdetails.UserDetailsService; | ||||
| import org.acegisecurity.userdetails.UsernameNotFoundException; | ||||
| 
 | ||||
| import org.acegisecurity.util.StringSplitUtils; | ||||
| 
 | ||||
| import org.apache.commons.codec.binary.Base64; | ||||
| import org.apache.commons.codec.digest.DigestUtils; | ||||
| import org.apache.commons.logging.Log; | ||||
| import org.apache.commons.logging.LogFactory; | ||||
| 
 | ||||
| import org.springframework.beans.factory.InitializingBean; | ||||
| 
 | ||||
| import org.springframework.context.MessageSource; | ||||
| import org.springframework.context.MessageSourceAware; | ||||
| import org.springframework.context.support.MessageSourceAccessor; | ||||
| 
 | ||||
| import org.springframework.util.Assert; | ||||
| import org.springframework.util.StringUtils; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import javax.servlet.Filter; | ||||
| @ -27,30 +62,6 @@ import javax.servlet.ServletResponse; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| 
 | ||||
| import org.acegisecurity.AcegiMessageSource; | ||||
| import org.acegisecurity.AuthenticationException; | ||||
| import org.acegisecurity.AuthenticationServiceException; | ||||
| import org.acegisecurity.BadCredentialsException; | ||||
| import org.acegisecurity.context.SecurityContextHolder; | ||||
| import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; | ||||
| import org.acegisecurity.providers.dao.UserCache; | ||||
| import org.acegisecurity.providers.dao.cache.NullUserCache; | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| import org.acegisecurity.userdetails.UserDetails; | ||||
| import org.acegisecurity.userdetails.UserDetailsService; | ||||
| import org.acegisecurity.userdetails.UsernameNotFoundException; | ||||
| import org.acegisecurity.util.StringSplitUtils; | ||||
| import org.apache.commons.codec.binary.Base64; | ||||
| import org.apache.commons.codec.digest.DigestUtils; | ||||
| import org.apache.commons.logging.Log; | ||||
| import org.apache.commons.logging.LogFactory; | ||||
| import org.springframework.beans.factory.InitializingBean; | ||||
| import org.springframework.context.MessageSource; | ||||
| import org.springframework.context.MessageSourceAware; | ||||
| import org.springframework.context.support.MessageSourceAccessor; | ||||
| import org.springframework.util.Assert; | ||||
| import org.springframework.util.StringUtils; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Processes a HTTP request's Digest authorization headers, putting the result | ||||
| @ -84,9 +95,9 @@ import org.springframework.util.StringUtils; | ||||
|  *  | ||||
|  * <p> | ||||
|  * If authentication fails, an {@link | ||||
|  * org.acegisecurity.ui.AuthenticationEntryPoint | ||||
|  * AuthenticationEntryPoint} implementation is called. This must always be | ||||
|  * {@link DigestProcessingFilterEntryPoint}, which will prompt the user to | ||||
|  * org.acegisecurity.ui.AuthenticationEntryPoint AuthenticationEntryPoint} | ||||
|  * implementation is called. This must always be {@link | ||||
|  * DigestProcessingFilterEntryPoint}, which will prompt the user to | ||||
|  * authenticate again via Digest authentication. | ||||
|  * </p> | ||||
|  *  | ||||
| @ -112,10 +123,11 @@ public class DigestProcessingFilter implements Filter, InitializingBean, | ||||
| 
 | ||||
|     //~ Instance fields ======================================================== | ||||
| 
 | ||||
|     private UserDetailsService userDetailsService; | ||||
|     private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); | ||||
|     private DigestProcessingFilterEntryPoint authenticationEntryPoint; | ||||
|     protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); | ||||
|     private UserCache userCache = new NullUserCache(); | ||||
|     private UserDetailsService userDetailsService; | ||||
|     private boolean passwordAlreadyEncoded = false; | ||||
| 
 | ||||
|     //~ Methods ================================================================ | ||||
| @ -369,10 +381,11 @@ public class DigestProcessingFilter implements Filter, InitializingBean, | ||||
|                     + "' with response: '" + responseDigest + "'"); | ||||
|             } | ||||
| 
 | ||||
|             UsernamePasswordAuthenticationToken authRequest = | ||||
|                     new UsernamePasswordAuthenticationToken(user, user.getPassword()); | ||||
|             UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(user, | ||||
|                     user.getPassword()); | ||||
| 
 | ||||
|             authRequest.setDetails(new WebAuthenticationDetails(httpRequest, false)); | ||||
|             authRequest.setDetails(authenticationDetailsSource.buildDetails( | ||||
|                     (HttpServletRequest) request)); | ||||
| 
 | ||||
|             SecurityContextHolder.getContext().setAuthentication(authRequest); | ||||
|         } | ||||
| @ -405,8 +418,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean, | ||||
|      * <code>response</code> independently. Provided as a static method to | ||||
|      * simplify the coding of user agents. | ||||
|      * | ||||
|      * @param passwordAlreadyEncoded true if the password argument is already encoded in | ||||
|      *                               the correct format. False if it is plain text. | ||||
|      * @param passwordAlreadyEncoded true if the password argument is already | ||||
|      *        encoded in the correct format. False if it is plain text. | ||||
|      * @param username the user's login name. | ||||
|      * @param realm the name of the realm. | ||||
|      * @param password the user's password in plaintext or ready-encoded. | ||||
| @ -419,7 +432,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean, | ||||
|      * | ||||
|      * @return the MD5 of the digest authentication response, encoded in hex | ||||
|      * | ||||
|      * @throws IllegalArgumentException if the supplied qop value is unsupported. | ||||
|      * @throws IllegalArgumentException if the supplied qop value is | ||||
|      *         unsupported. | ||||
|      */ | ||||
|     public static String generateDigest(boolean passwordAlreadyEncoded, | ||||
|         String username, String realm, String password, String httpMethod, | ||||
| @ -454,10 +468,6 @@ public class DigestProcessingFilter implements Filter, InitializingBean, | ||||
|         return digestMd5; | ||||
|     } | ||||
| 
 | ||||
|     public UserDetailsService getUserDetailsService() { | ||||
|         return userDetailsService; | ||||
|     } | ||||
| 
 | ||||
|     public DigestProcessingFilterEntryPoint getAuthenticationEntryPoint() { | ||||
|         return authenticationEntryPoint; | ||||
|     } | ||||
| @ -466,10 +476,17 @@ public class DigestProcessingFilter implements Filter, InitializingBean, | ||||
|         return userCache; | ||||
|     } | ||||
| 
 | ||||
|     public UserDetailsService getUserDetailsService() { | ||||
|         return userDetailsService; | ||||
|     } | ||||
| 
 | ||||
|     public void init(FilterConfig ignored) throws ServletException {} | ||||
| 
 | ||||
|     public void setUserDetailsService(UserDetailsService authenticationDao) { | ||||
|         this.userDetailsService = authenticationDao; | ||||
|     public void setAuthenticationDetailsSource( | ||||
|         AuthenticationDetailsSource authenticationDetailsSource) { | ||||
|         Assert.notNull(authenticationDetailsSource, | ||||
|             "AuthenticationDetailsSource required"); | ||||
|         this.authenticationDetailsSource = authenticationDetailsSource; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthenticationEntryPoint( | ||||
| @ -488,4 +505,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean, | ||||
|     public void setUserCache(UserCache userCache) { | ||||
|         this.userCache = userCache; | ||||
|     } | ||||
| 
 | ||||
|     public void setUserDetailsService(UserDetailsService authenticationDao) { | ||||
|         this.userDetailsService = authenticationDao; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -19,7 +19,8 @@ import org.acegisecurity.Authentication; | ||||
| 
 | ||||
| import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken; | ||||
| 
 | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSource; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSourceImpl; | ||||
| 
 | ||||
| import org.acegisecurity.userdetails.UserDetails; | ||||
| import org.acegisecurity.userdetails.UserDetailsService; | ||||
| @ -116,6 +117,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, | ||||
| 
 | ||||
|     //~ Instance fields ======================================================== | ||||
| 
 | ||||
|     private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); | ||||
|     private String key; | ||||
|     private String parameter = DEFAULT_PARAMETER; | ||||
|     private UserDetailsService userDetailsService; | ||||
| @ -232,8 +234,8 @@ public class TokenBasedRememberMeServices implements RememberMeServices, | ||||
| 
 | ||||
|                         RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(this.key, | ||||
|                                 userDetails, userDetails.getAuthorities()); | ||||
|                         auth.setDetails(new WebAuthenticationDetails(request, | ||||
|                                 false)); | ||||
|                         auth.setDetails(authenticationDetailsSource.buildDetails( | ||||
|                                 (HttpServletRequest) request)); | ||||
| 
 | ||||
|                         return auth; | ||||
|                     } else { | ||||
| @ -347,15 +349,23 @@ public class TokenBasedRememberMeServices implements RememberMeServices, | ||||
|         return cookie; | ||||
|     } | ||||
| 
 | ||||
|     protected Cookie makeValidCookie(long expiryTime, String tokenValueBase64, HttpServletRequest request) { | ||||
|     protected Cookie makeValidCookie(long expiryTime, String tokenValueBase64, | ||||
|         HttpServletRequest request) { | ||||
|         Cookie cookie = new Cookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, | ||||
|                 tokenValueBase64); | ||||
|         cookie.setMaxAge(60 * 60 * 24 * 365 * 5); // 5 years | ||||
|         cookie.setPath(request.getContextPath()); | ||||
|          | ||||
| 
 | ||||
|         return cookie; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthenticationDetailsSource( | ||||
|         AuthenticationDetailsSource authenticationDetailsSource) { | ||||
|         Assert.notNull(authenticationDetailsSource, | ||||
|             "AuthenticationDetailsSource required"); | ||||
|         this.authenticationDetailsSource = authenticationDetailsSource; | ||||
|     } | ||||
| 
 | ||||
|     public void setKey(String key) { | ||||
|         this.key = key; | ||||
|     } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* Copyright 2004, 2005 Acegi Technology Pty Limited | ||||
| /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -15,7 +15,45 @@ | ||||
| 
 | ||||
| package org.acegisecurity.ui.switchuser; | ||||
| 
 | ||||
| import org.acegisecurity.AccountExpiredException; | ||||
| import org.acegisecurity.AcegiMessageSource; | ||||
| import org.acegisecurity.Authentication; | ||||
| import org.acegisecurity.AuthenticationCredentialsNotFoundException; | ||||
| import org.acegisecurity.AuthenticationException; | ||||
| import org.acegisecurity.CredentialsExpiredException; | ||||
| import org.acegisecurity.DisabledException; | ||||
| import org.acegisecurity.GrantedAuthority; | ||||
| import org.acegisecurity.LockedException; | ||||
| 
 | ||||
| import org.acegisecurity.context.SecurityContextHolder; | ||||
| 
 | ||||
| import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent; | ||||
| 
 | ||||
| import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; | ||||
| 
 | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSource; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSourceImpl; | ||||
| 
 | ||||
| import org.acegisecurity.userdetails.UserDetails; | ||||
| import org.acegisecurity.userdetails.UserDetailsService; | ||||
| import org.acegisecurity.userdetails.UsernameNotFoundException; | ||||
| 
 | ||||
| import org.apache.commons.logging.Log; | ||||
| import org.apache.commons.logging.LogFactory; | ||||
| 
 | ||||
| import org.springframework.beans.BeansException; | ||||
| import org.springframework.beans.factory.InitializingBean; | ||||
| 
 | ||||
| import org.springframework.context.ApplicationEventPublisher; | ||||
| import org.springframework.context.ApplicationEventPublisherAware; | ||||
| import org.springframework.context.MessageSource; | ||||
| import org.springframework.context.MessageSourceAware; | ||||
| import org.springframework.context.support.MessageSourceAccessor; | ||||
| 
 | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| @ -29,33 +67,6 @@ import javax.servlet.ServletResponse; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| 
 | ||||
| import org.acegisecurity.AccountExpiredException; | ||||
| import org.acegisecurity.AcegiMessageSource; | ||||
| import org.acegisecurity.Authentication; | ||||
| import org.acegisecurity.AuthenticationCredentialsNotFoundException; | ||||
| import org.acegisecurity.AuthenticationException; | ||||
| import org.acegisecurity.CredentialsExpiredException; | ||||
| import org.acegisecurity.DisabledException; | ||||
| import org.acegisecurity.GrantedAuthority; | ||||
| import org.acegisecurity.LockedException; | ||||
| import org.acegisecurity.context.SecurityContextHolder; | ||||
| import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent; | ||||
| import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| import org.acegisecurity.userdetails.UserDetails; | ||||
| import org.acegisecurity.userdetails.UserDetailsService; | ||||
| import org.acegisecurity.userdetails.UsernameNotFoundException; | ||||
| import org.apache.commons.logging.Log; | ||||
| import org.apache.commons.logging.LogFactory; | ||||
| import org.springframework.beans.BeansException; | ||||
| import org.springframework.beans.factory.InitializingBean; | ||||
| import org.springframework.context.ApplicationEventPublisher; | ||||
| import org.springframework.context.ApplicationEventPublisherAware; | ||||
| import org.springframework.context.MessageSource; | ||||
| import org.springframework.context.MessageSourceAware; | ||||
| import org.springframework.context.support.MessageSourceAccessor; | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Switch User processing filter responsible for user context switching. | ||||
| @ -104,7 +115,6 @@ import org.springframework.util.Assert; | ||||
|  * </pre> | ||||
|  * </p> | ||||
|  * | ||||
|  * | ||||
|  * @author Mark St.Godard | ||||
|  * @version $Id$ | ||||
|  * | ||||
| @ -124,15 +134,16 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, | ||||
|     //~ Instance fields ======================================================== | ||||
| 
 | ||||
|     private ApplicationEventPublisher eventPublisher; | ||||
| 
 | ||||
|     // ~ Instance fields | ||||
|     // ======================================================== | ||||
|     private UserDetailsService userDetailsService; | ||||
|     private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); | ||||
|     protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); | ||||
|     private String exitUserUrl = "/j_acegi_exit_user"; | ||||
|     private String switchUserUrl = "/j_acegi_switch_user"; | ||||
|     private String targetUrl; | ||||
| 
 | ||||
|     // ~ Instance fields | ||||
|     // ======================================================== | ||||
|     private UserDetailsService userDetailsService; | ||||
| 
 | ||||
|     //~ Methods ================================================================ | ||||
| 
 | ||||
|     public void afterPropertiesSet() throws Exception { | ||||
| @ -160,369 +171,344 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, | ||||
|         Authentication current = SecurityContextHolder.getContext() | ||||
|                                                       .getAuthentication(); | ||||
| 
 | ||||
|             if (null == current) { | ||||
|                 throw new AuthenticationCredentialsNotFoundException(messages | ||||
|                         .getMessage("SwitchUserProcessingFilter.noCurrentUser", | ||||
|                             "No current user associated with this request")); | ||||
|             } | ||||
| 
 | ||||
|             // check to see if the current user did actual switch to another user | ||||
|             // if so, get the original source user so we can switch back | ||||
|             Authentication original = getSourceAuthentication(current); | ||||
| 
 | ||||
|             if (original == null) { | ||||
|                 logger.error( | ||||
|                     "Could not find original user Authentication object!"); | ||||
|                 throw new AuthenticationCredentialsNotFoundException(messages | ||||
|                         .getMessage( | ||||
|                             "SwitchUserProcessingFilter.noOriginalAuthentication", | ||||
|                             "Could not find original Authentication object")); | ||||
|             } | ||||
| 
 | ||||
|             // get the source user details | ||||
|             UserDetails originalUser = null; | ||||
|             Object obj = original.getPrincipal(); | ||||
| 
 | ||||
|             if ((obj != null) && obj instanceof UserDetails) { | ||||
|                 originalUser = (UserDetails) obj; | ||||
|             } | ||||
| 
 | ||||
|             // publish event | ||||
|             if (this.eventPublisher != null) { | ||||
|                 eventPublisher.publishEvent(new AuthenticationSwitchUserEvent( | ||||
|                         current, originalUser)); | ||||
|             } | ||||
| 
 | ||||
|             return original; | ||||
|         if (null == current) { | ||||
|             throw new AuthenticationCredentialsNotFoundException(messages | ||||
|                 .getMessage("SwitchUserProcessingFilter.noCurrentUser", | ||||
|                     "No current user associated with this request")); | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Attempt to switch to another user. If the user does not exist or | ||||
|          * is not active, return null. | ||||
|          * | ||||
|          * @param request The http request | ||||
|          * | ||||
|          * @return The new <code>Authentication</code> request if | ||||
|          *         successfully switched to another user, | ||||
|          *         <code>null</code> otherwise. | ||||
|          * | ||||
|          * @throws AuthenticationException | ||||
|          * @throws UsernameNotFoundException If the target user is not | ||||
|          *         found. | ||||
|          * @throws LockedException DOCUMENT ME! | ||||
|          * @throws DisabledException If the target user is disabled. | ||||
|          * @throws AccountExpiredException If the target user account is | ||||
|          *         expired. | ||||
|          * @throws CredentialsExpiredException If the target user | ||||
|          *         credentials are expired. | ||||
|          */ | ||||
|         protected Authentication attemptSwitchUser( | ||||
|                 HttpServletRequest request) throws AuthenticationException { | ||||
|             UsernamePasswordAuthenticationToken targetUserRequest = null; | ||||
|         // check to see if the current user did actual switch to another user | ||||
|         // if so, get the original source user so we can switch back | ||||
|         Authentication original = getSourceAuthentication(current); | ||||
| 
 | ||||
|             String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY); | ||||
|         if (original == null) { | ||||
|             logger.error("Could not find original user Authentication object!"); | ||||
|             throw new AuthenticationCredentialsNotFoundException(messages | ||||
|                 .getMessage("SwitchUserProcessingFilter.noOriginalAuthentication", | ||||
|                     "Could not find original Authentication object")); | ||||
|         } | ||||
| 
 | ||||
|             if (username == null) { | ||||
|                 username = ""; | ||||
|         // get the source user details | ||||
|         UserDetails originalUser = null; | ||||
|         Object obj = original.getPrincipal(); | ||||
| 
 | ||||
|         if ((obj != null) && obj instanceof UserDetails) { | ||||
|             originalUser = (UserDetails) obj; | ||||
|         } | ||||
| 
 | ||||
|         // publish event | ||||
|         if (this.eventPublisher != null) { | ||||
|             eventPublisher.publishEvent(new AuthenticationSwitchUserEvent( | ||||
|                     current, originalUser)); | ||||
|         } | ||||
| 
 | ||||
|         return original; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Attempt to switch to another user. If the user does not exist or is not | ||||
|      * active, return null. | ||||
|      * | ||||
|      * @param request The http request | ||||
|      * | ||||
|      * @return The new <code>Authentication</code> request if successfully | ||||
|      *         switched to another user, <code>null</code> otherwise. | ||||
|      * | ||||
|      * @throws AuthenticationException | ||||
|      * @throws UsernameNotFoundException If the target user is not found. | ||||
|      * @throws LockedException DOCUMENT ME! | ||||
|      * @throws DisabledException If the target user is disabled. | ||||
|      * @throws AccountExpiredException If the target user account is expired. | ||||
|      * @throws CredentialsExpiredException If the target user credentials are | ||||
|      *         expired. | ||||
|      */ | ||||
|     protected Authentication attemptSwitchUser(HttpServletRequest request) | ||||
|         throws AuthenticationException { | ||||
|         UsernamePasswordAuthenticationToken targetUserRequest = null; | ||||
| 
 | ||||
|         String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY); | ||||
| 
 | ||||
|         if (username == null) { | ||||
|             username = ""; | ||||
|         } | ||||
| 
 | ||||
|         if (logger.isDebugEnabled()) { | ||||
|             logger.debug("Attempt to switch to user [" + username + "]"); | ||||
|         } | ||||
| 
 | ||||
|         // load the user by name | ||||
|         UserDetails targetUser = this.userDetailsService.loadUserByUsername(username); | ||||
| 
 | ||||
|         // user not found | ||||
|         if (targetUser == null) { | ||||
|             throw new UsernameNotFoundException(messages.getMessage( | ||||
|                     "SwitchUserProcessingFilter.usernameNotFound", | ||||
|                     new Object[] {username}, "Username {0} not found")); | ||||
|         } | ||||
| 
 | ||||
|         // account is expired | ||||
|         if (!targetUser.isAccountNonLocked()) { | ||||
|             throw new LockedException(messages.getMessage( | ||||
|                     "SwitchUserProcessingFilter.locked", | ||||
|                     "User account is locked")); | ||||
|         } | ||||
| 
 | ||||
|         // user is disabled | ||||
|         if (!targetUser.isEnabled()) { | ||||
|             throw new DisabledException(messages.getMessage( | ||||
|                     "SwitchUserProcessingFilter.disabled", "User is disabled")); | ||||
|         } | ||||
| 
 | ||||
|         // account is expired | ||||
|         if (!targetUser.isAccountNonExpired()) { | ||||
|             throw new AccountExpiredException(messages.getMessage( | ||||
|                     "SwitchUserProcessingFilter.expired", | ||||
|                     "User account has expired")); | ||||
|         } | ||||
| 
 | ||||
|         // credentials expired | ||||
|         if (!targetUser.isCredentialsNonExpired()) { | ||||
|             throw new CredentialsExpiredException(messages.getMessage( | ||||
|                     "SwitchUserProcessingFilter.credentialsExpired", | ||||
|                     "User credentials have expired")); | ||||
|         } | ||||
| 
 | ||||
|         // ok, create the switch user token | ||||
|         targetUserRequest = createSwitchUserToken(request, username, targetUser); | ||||
| 
 | ||||
|         if (logger.isDebugEnabled()) { | ||||
|             logger.debug("Switch User Token [" + targetUserRequest + "]"); | ||||
|         } | ||||
| 
 | ||||
|         // publish event | ||||
|         if (this.eventPublisher != null) { | ||||
|             eventPublisher.publishEvent(new AuthenticationSwitchUserEvent( | ||||
|                     SecurityContextHolder.getContext().getAuthentication(), | ||||
|                     targetUser)); | ||||
|         } | ||||
| 
 | ||||
|         return targetUserRequest; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create a switch user token that contains an additional | ||||
|      * <tt>GrantedAuthority</tt> that contains the original | ||||
|      * <code>Authentication</code> object. | ||||
|      * | ||||
|      * @param request The http servlet request. | ||||
|      * @param username The username of target user | ||||
|      * @param targetUser The target user | ||||
|      * | ||||
|      * @return The authentication token | ||||
|      * | ||||
|      * @see SwitchUserGrantedAuthority | ||||
|      */ | ||||
|     private UsernamePasswordAuthenticationToken createSwitchUserToken( | ||||
|         HttpServletRequest request, String username, UserDetails targetUser) { | ||||
|         UsernamePasswordAuthenticationToken targetUserRequest; | ||||
| 
 | ||||
|         // grant an additional authority that contains the original Authentication object | ||||
|         // which will be used to 'exit' from the current switched user. | ||||
|         Authentication currentAuth = SecurityContextHolder.getContext() | ||||
|                                                           .getAuthentication(); | ||||
|         GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR, | ||||
|                 currentAuth); | ||||
| 
 | ||||
|         // get the original authorities | ||||
|         List orig = Arrays.asList(targetUser.getAuthorities()); | ||||
| 
 | ||||
|         // add the new switch user authority | ||||
|         List newAuths = new ArrayList(orig); | ||||
|         newAuths.add(switchAuthority); | ||||
| 
 | ||||
|         GrantedAuthority[] authorities = {}; | ||||
|         authorities = (GrantedAuthority[]) newAuths.toArray(authorities); | ||||
| 
 | ||||
|         // create the new authentication token | ||||
|         targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser, | ||||
|                 targetUser.getPassword(), authorities); | ||||
| 
 | ||||
|         // set details | ||||
|         targetUserRequest.setDetails(authenticationDetailsSource.buildDetails( | ||||
|                 (HttpServletRequest) request)); | ||||
| 
 | ||||
|         return targetUserRequest; | ||||
|     } | ||||
| 
 | ||||
|     public void destroy() {} | ||||
| 
 | ||||
|     /** | ||||
|      * @see javax.servlet.Filter#doFilter | ||||
|      */ | ||||
|     public void doFilter(ServletRequest request, ServletResponse response, | ||||
|         FilterChain chain) throws IOException, ServletException { | ||||
|         Assert.isInstanceOf(HttpServletRequest.class, request); | ||||
|         Assert.isInstanceOf(HttpServletResponse.class, response); | ||||
| 
 | ||||
|         HttpServletRequest httpRequest = (HttpServletRequest) request; | ||||
|         HttpServletResponse httpResponse = (HttpServletResponse) response; | ||||
| 
 | ||||
|         // check for switch or exit request | ||||
|         if (requiresSwitchUser(httpRequest)) { | ||||
|             // if set, attempt switch and store original | ||||
|             Authentication targetUser = attemptSwitchUser(httpRequest); | ||||
| 
 | ||||
|             // update the current context to the new target user | ||||
|             SecurityContextHolder.getContext().setAuthentication(targetUser); | ||||
| 
 | ||||
|             // redirect to target url | ||||
|             httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest | ||||
|                     .getContextPath() + targetUrl)); | ||||
| 
 | ||||
|             return; | ||||
|         } else if (requiresExitUser(httpRequest)) { | ||||
|             // get the original authentication object (if exists) | ||||
|             Authentication originalUser = attemptExitUser(httpRequest); | ||||
| 
 | ||||
|             // update the current context back to the original user | ||||
|             SecurityContextHolder.getContext().setAuthentication(originalUser); | ||||
| 
 | ||||
|             // redirect to target url | ||||
|             httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest | ||||
|                     .getContextPath() + targetUrl)); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         chain.doFilter(request, response); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Find the original <code>Authentication</code> object from the current | ||||
|      * user's granted authorities. A successfully switched user should have a | ||||
|      * <code>SwitchUserGrantedAuthority</code> that contains the original | ||||
|      * source user <code>Authentication</code> object. | ||||
|      * | ||||
|      * @param current The current  <code>Authentication</code> object | ||||
|      * | ||||
|      * @return The source user <code>Authentication</code> object or | ||||
|      *         <code>null</code> otherwise. | ||||
|      */ | ||||
|     private Authentication getSourceAuthentication(Authentication current) { | ||||
|         Authentication original = null; | ||||
| 
 | ||||
|         // iterate over granted authorities and find the 'switch user' authority | ||||
|         GrantedAuthority[] authorities = current.getAuthorities(); | ||||
| 
 | ||||
|         for (int i = 0; i < authorities.length; i++) { | ||||
|             // check for switch user type of authority | ||||
|             if (authorities[i] instanceof SwitchUserGrantedAuthority) { | ||||
|                 original = ((SwitchUserGrantedAuthority) authorities[i]) | ||||
|                     .getSource(); | ||||
|                 logger.debug("Found original switch user granted authority [" | ||||
|                     + original + "]"); | ||||
|             } | ||||
| 
 | ||||
|             if (logger.isDebugEnabled()) { | ||||
|                 logger.debug("Attempt to switch to user [" + username + "]"); | ||||
|             } | ||||
| 
 | ||||
|             // load the user by name | ||||
|             UserDetails targetUser = this.userDetailsService | ||||
|                     .loadUserByUsername(username); | ||||
| 
 | ||||
|             // user not found | ||||
|             if (targetUser == null) { | ||||
|                 throw new UsernameNotFoundException(messages.getMessage( | ||||
|                         "SwitchUserProcessingFilter.usernameNotFound", | ||||
|                         new Object[] {username}, | ||||
|                         "Username {0} not found")); | ||||
|             } | ||||
| 
 | ||||
|             // account is expired | ||||
|             if (!targetUser.isAccountNonLocked()) { | ||||
|                 throw new LockedException(messages.getMessage( | ||||
|                         "SwitchUserProcessingFilter.locked", | ||||
|                         "User account is locked")); | ||||
|             } | ||||
| 
 | ||||
|             // user is disabled | ||||
|             if (!targetUser.isEnabled()) { | ||||
|                 throw new DisabledException(messages.getMessage( | ||||
|                         "SwitchUserProcessingFilter.disabled", | ||||
|                         "User is disabled")); | ||||
|             } | ||||
| 
 | ||||
|             // account is expired | ||||
|             if (!targetUser.isAccountNonExpired()) { | ||||
|                 throw new AccountExpiredException(messages.getMessage( | ||||
|                         "SwitchUserProcessingFilter.expired", | ||||
|                         "User account has expired")); | ||||
|             } | ||||
| 
 | ||||
|             // credentials expired | ||||
|             if (!targetUser.isCredentialsNonExpired()) { | ||||
|                 throw new CredentialsExpiredException(messages | ||||
|                         .getMessage( | ||||
|                             "SwitchUserProcessingFilter.credentialsExpired", | ||||
|                             "User credentials have expired")); | ||||
|             } | ||||
| 
 | ||||
|             // ok, create the switch user token | ||||
|             targetUserRequest = createSwitchUserToken(request, | ||||
|                     username, targetUser); | ||||
| 
 | ||||
|             if (logger.isDebugEnabled()) { | ||||
|                 logger.debug("Switch User Token [" + targetUserRequest + "]"); | ||||
|             } | ||||
| 
 | ||||
|             // publish event | ||||
|             if (this.eventPublisher != null) { | ||||
|                 eventPublisher.publishEvent(new AuthenticationSwitchUserEvent( | ||||
|                         SecurityContextHolder.getContext().getAuthentication(), | ||||
|                         targetUser)); | ||||
|             } | ||||
| 
 | ||||
|             return targetUserRequest; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Create a switch user token that contains an additional | ||||
|          * <tt>GrantedAuthority</tt> that contains the original | ||||
|          * <code>Authentication</code> object. | ||||
|          * | ||||
|          * @param request The http servlet request. | ||||
|          * @param username The username of target user | ||||
|          * @param targetUser The target user | ||||
|          * | ||||
|          * @return The authentication token | ||||
|          * | ||||
|          * @see SwitchUserGrantedAuthority | ||||
|          */ | ||||
|         private UsernamePasswordAuthenticationToken createSwitchUserToken( | ||||
|             HttpServletRequest request, String username, | ||||
|             UserDetails targetUser) { | ||||
|             UsernamePasswordAuthenticationToken targetUserRequest; | ||||
|         return original; | ||||
|     } | ||||
| 
 | ||||
|             // grant an additional authority that contains the original Authentication object | ||||
|             // which will be used to 'exit' from the current switched user. | ||||
|             Authentication currentAuth = SecurityContextHolder.getContext() | ||||
|                                                               .getAuthentication(); | ||||
|             GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR, | ||||
|                     currentAuth); | ||||
|     public void init(FilterConfig ignored) throws ServletException {} | ||||
| 
 | ||||
|             // get the original authorities | ||||
|             List orig = Arrays.asList(targetUser.getAuthorities()); | ||||
|     /** | ||||
|      * Checks the request URI for the presence of <tt>exitUserUrl</tt>. | ||||
|      * | ||||
|      * @param request The http servlet request | ||||
|      * | ||||
|      * @return <code>true</code> if the request requires a exit user, | ||||
|      *         <code>false</code> otherwise. | ||||
|      * | ||||
|      * @see SwitchUserProcessingFilter#exitUserUrl | ||||
|      */ | ||||
|     protected boolean requiresExitUser(HttpServletRequest request) { | ||||
|         String uri = stripUri(request); | ||||
| 
 | ||||
|             // add the new switch user authority | ||||
|             List newAuths = new ArrayList(orig); | ||||
|             newAuths.add(switchAuthority); | ||||
|         return uri.endsWith(request.getContextPath() + exitUserUrl); | ||||
|     } | ||||
| 
 | ||||
|             GrantedAuthority[] authorities = {}; | ||||
|             authorities = (GrantedAuthority[]) newAuths.toArray(authorities); | ||||
|     /** | ||||
|      * Checks the request URI for the presence of <tt>switchUserUrl</tt>. | ||||
|      * | ||||
|      * @param request The http servlet request | ||||
|      * | ||||
|      * @return <code>true</code> if the request requires a switch, | ||||
|      *         <code>false</code> otherwise. | ||||
|      * | ||||
|      * @see SwitchUserProcessingFilter#switchUserUrl | ||||
|      */ | ||||
|     protected boolean requiresSwitchUser(HttpServletRequest request) { | ||||
|         String uri = stripUri(request); | ||||
| 
 | ||||
|             // create the new authentication token | ||||
|             targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser, | ||||
|                     targetUser.getPassword(), authorities); | ||||
|         return uri.endsWith(request.getContextPath() + switchUserUrl); | ||||
|     } | ||||
| 
 | ||||
|             // set details | ||||
|             targetUserRequest.setDetails(new WebAuthenticationDetails( | ||||
|                     request, false)); | ||||
|     public void setApplicationEventPublisher( | ||||
|         ApplicationEventPublisher eventPublisher) throws BeansException { | ||||
|         this.eventPublisher = eventPublisher; | ||||
|     } | ||||
| 
 | ||||
|             return targetUserRequest; | ||||
|     public void setAuthenticationDetailsSource( | ||||
|         AuthenticationDetailsSource authenticationDetailsSource) { | ||||
|         Assert.notNull(authenticationDetailsSource, | ||||
|             "AuthenticationDetailsSource required"); | ||||
|         this.authenticationDetailsSource = authenticationDetailsSource; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Set the URL to respond to exit user processing. | ||||
|      * | ||||
|      * @param exitUserUrl The exit user URL. | ||||
|      */ | ||||
|     public void setExitUserUrl(String exitUserUrl) { | ||||
|         this.exitUserUrl = exitUserUrl; | ||||
|     } | ||||
| 
 | ||||
|     public void setMessageSource(MessageSource messageSource) { | ||||
|         this.messages = new MessageSourceAccessor(messageSource); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Set the URL to respond to switch user processing. | ||||
|      * | ||||
|      * @param switchUserUrl The switch user URL. | ||||
|      */ | ||||
|     public void setSwitchUserUrl(String switchUserUrl) { | ||||
|         this.switchUserUrl = switchUserUrl; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the URL to go to after a successful switch / exit user request. | ||||
|      * | ||||
|      * @param targetUrl The target url. | ||||
|      */ | ||||
|     public void setTargetUrl(String targetUrl) { | ||||
|         this.targetUrl = targetUrl; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the authentication data access object. | ||||
|      * | ||||
|      * @param authenticationDao The authentication dao | ||||
|      */ | ||||
|     public void setUserDetailsService(UserDetailsService authenticationDao) { | ||||
|         this.userDetailsService = authenticationDao; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Strips any content after the ';' in the request URI | ||||
|      * | ||||
|      * @param request The http request | ||||
|      * | ||||
|      * @return The stripped uri | ||||
|      */ | ||||
|     private static String stripUri(HttpServletRequest request) { | ||||
|         String uri = request.getRequestURI(); | ||||
|         int idx = uri.indexOf(';'); | ||||
| 
 | ||||
|         if (idx > 0) { | ||||
|             uri = uri.substring(0, idx); | ||||
|         } | ||||
| 
 | ||||
|         public void destroy() {} | ||||
| 
 | ||||
|         /** | ||||
|          * @see javax.servlet.Filter#doFilter | ||||
|          */ | ||||
|         public void doFilter(ServletRequest request, | ||||
|             ServletResponse response, FilterChain chain) | ||||
|             throws IOException, ServletException { | ||||
|             Assert.isInstanceOf(HttpServletRequest.class, request); | ||||
|             Assert.isInstanceOf(HttpServletResponse.class, response); | ||||
| 
 | ||||
|             HttpServletRequest httpRequest = (HttpServletRequest) request; | ||||
|             HttpServletResponse httpResponse = (HttpServletResponse) response; | ||||
| 
 | ||||
|             // check for switch or exit request | ||||
|             if (requiresSwitchUser(httpRequest)) { | ||||
|                 // if set, attempt switch and store original | ||||
|                 Authentication targetUser = attemptSwitchUser(httpRequest); | ||||
| 
 | ||||
|                 // update the current context to the new target user | ||||
|                 SecurityContextHolder.getContext() | ||||
|                                      .setAuthentication(targetUser); | ||||
| 
 | ||||
|                 // redirect to target url | ||||
|                 httpResponse.sendRedirect(httpResponse | ||||
|                         .encodeRedirectURL(httpRequest | ||||
|                                 .getContextPath() + targetUrl)); | ||||
| 
 | ||||
|                 return; | ||||
|             } else if (requiresExitUser(httpRequest)) { | ||||
|                 // get the original authentication object (if exists) | ||||
|                 Authentication originalUser = attemptExitUser(httpRequest); | ||||
| 
 | ||||
|                 // update the current context back to the original user | ||||
|                 SecurityContextHolder.getContext() | ||||
|                                      .setAuthentication(originalUser); | ||||
| 
 | ||||
|                 // redirect to target url | ||||
|                 httpResponse.sendRedirect(httpResponse.encodeRedirectURL( | ||||
|                         httpRequest.getContextPath() + targetUrl)); | ||||
| 
 | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             chain.doFilter(request, response); | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Find the original <code>Authentication</code> object from | ||||
|          * the current user's granted authorities. A successfully switched | ||||
|          * user should have a <code>SwitchUserGrantedAuthority</code> | ||||
|          * that contains the original source user <code>Authentication</code> | ||||
|          * object. | ||||
|          * | ||||
|          * @param current The current  <code>Authentication</code> | ||||
|          *        object | ||||
|          * | ||||
|          * @return The source user <code>Authentication</code> | ||||
|          *         object or <code>null</code> otherwise. | ||||
|          */ | ||||
|         private Authentication getSourceAuthentication( | ||||
|             Authentication current) { | ||||
|             Authentication original = null; | ||||
| 
 | ||||
|             // iterate over granted authorities and find the 'switch user' authority | ||||
|             GrantedAuthority[] authorities = current | ||||
|                 .getAuthorities(); | ||||
| 
 | ||||
|             for (int i = 0; i < authorities.length; i++) { | ||||
|                 // check for switch user type of authority | ||||
|                 if (authorities[i] instanceof SwitchUserGrantedAuthority) { | ||||
|                     original = ((SwitchUserGrantedAuthority) authorities[i]) | ||||
|                         .getSource(); | ||||
|                     logger.debug( | ||||
|                         "Found original switch user granted authority [" | ||||
|                         + original + "]"); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return original; | ||||
|         } | ||||
| 
 | ||||
|         public void init(FilterConfig ignored) | ||||
|             throws ServletException {} | ||||
| 
 | ||||
|         /** | ||||
|          * Checks the request URI for the presence | ||||
|          * of <tt>exitUserUrl</tt>. | ||||
|          * | ||||
|          * @param request The http servlet request | ||||
|          * | ||||
|          * @return <code>true</code> if the request requires a exit user, | ||||
|          *         <code>false</code> otherwise. | ||||
|          * | ||||
|          * @see SwitchUserProcessingFilter#exitUserUrl | ||||
|          */ | ||||
|         protected boolean requiresExitUser( | ||||
|             HttpServletRequest request) { | ||||
|             String uri = stripUri(request); | ||||
| 
 | ||||
|             return uri.endsWith(request | ||||
|                     .getContextPath() + exitUserUrl); | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Checks the request URI for the presence of <tt>switchUserUrl</tt>. | ||||
|          * | ||||
|          * @param request The http servlet request | ||||
|          * | ||||
|          * @return <code>true</code> if the request requires a switch, | ||||
|          *         <code>false</code> otherwise. | ||||
|          * | ||||
|          * @see SwitchUserProcessingFilter#switchUserUrl | ||||
|          */ | ||||
|         protected boolean requiresSwitchUser( | ||||
|             HttpServletRequest request) { | ||||
|             String uri = stripUri(request); | ||||
| 
 | ||||
|             return uri.endsWith(request.getContextPath() + switchUserUrl); | ||||
|         } | ||||
| 
 | ||||
|         public void setApplicationEventPublisher( | ||||
|             ApplicationEventPublisher eventPublisher) | ||||
|             throws BeansException { | ||||
|             this.eventPublisher = eventPublisher; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Sets the authentication data access object. | ||||
|          * | ||||
|          * @param authenticationDao The authentication dao | ||||
|          */ | ||||
|         public void setUserDetailsService( | ||||
|             UserDetailsService authenticationDao) { | ||||
|             this.userDetailsService = authenticationDao; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Set the URL to respond to exit user processing. | ||||
|          * | ||||
|          * @param exitUserUrl The exit user URL. | ||||
|          */ | ||||
|         public void setExitUserUrl( | ||||
|             String exitUserUrl) { | ||||
|             this.exitUserUrl = exitUserUrl; | ||||
|         } | ||||
| 
 | ||||
|         public void setMessageSource( | ||||
|             MessageSource messageSource) { | ||||
|             this.messages = new MessageSourceAccessor(messageSource); | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Set the URL to respond to switch user processing. | ||||
|          * | ||||
|          * @param switchUserUrl The switch user URL. | ||||
|          */ | ||||
|         public void setSwitchUserUrl(String switchUserUrl) { | ||||
|             this.switchUserUrl = switchUserUrl; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Sets the URL to go to after a successful switch / exit user | ||||
|          * request. | ||||
|          * | ||||
|          * @param targetUrl The target url. | ||||
|          */ | ||||
|         public void setTargetUrl( | ||||
|             String targetUrl) { | ||||
|             this.targetUrl = targetUrl; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Strips any content after the ';' in the request URI | ||||
|          * | ||||
|          * @param request The http request | ||||
|          * | ||||
|          * @return The stripped uri | ||||
|          */ | ||||
|         private static String stripUri(HttpServletRequest request) { | ||||
|             String uri = request.getRequestURI(); | ||||
|             int idx = uri.indexOf(';'); | ||||
| 
 | ||||
|             if (idx > 0) { | ||||
|                 uri = uri.substring(0, | ||||
|                         idx); | ||||
|             } | ||||
| 
 | ||||
|             return uri; | ||||
|         } | ||||
|         return uri; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* Copyright 2004, 2005 Acegi Technology Pty Limited | ||||
| /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -17,9 +17,10 @@ package org.acegisecurity.ui.webapp; | ||||
| 
 | ||||
| import org.acegisecurity.Authentication; | ||||
| import org.acegisecurity.AuthenticationException; | ||||
| 
 | ||||
| import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; | ||||
| 
 | ||||
| import org.acegisecurity.ui.AbstractProcessingFilter; | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| 
 | ||||
| import javax.servlet.FilterConfig; | ||||
| import javax.servlet.ServletException; | ||||
| @ -55,15 +56,6 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { | ||||
| 
 | ||||
|     //~ Methods ================================================================ | ||||
| 
 | ||||
|     /** | ||||
|      * This filter by default responds to <code>/j_acegi_security_check</code>. | ||||
|      * | ||||
|      * @return the default | ||||
|      */ | ||||
|     public String getDefaultFilterProcessesUrl() { | ||||
|         return "/j_acegi_security_check"; | ||||
|     } | ||||
| 
 | ||||
|     public Authentication attemptAuthentication(HttpServletRequest request) | ||||
|         throws AuthenticationException { | ||||
|         String username = obtainUsername(request); | ||||
| @ -84,28 +76,23 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { | ||||
|         setDetails(request, authRequest); | ||||
| 
 | ||||
|         // Place the last username attempted into HttpSession for views | ||||
|         request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, | ||||
|             username); | ||||
|         request.getSession() | ||||
|                .setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username); | ||||
| 
 | ||||
|         return this.getAuthenticationManager().authenticate(authRequest); | ||||
|     } | ||||
| 
 | ||||
|     public void init(FilterConfig filterConfig) throws ServletException {} | ||||
| 
 | ||||
|     /** | ||||
|      * Provided so that subclasses may configure what is put into the | ||||
|      * authentication request's details property. The default implementation | ||||
|      * simply constructs {@link WebAuthenticationDetails}. | ||||
|      * This filter by default responds to <code>/j_acegi_security_check</code>. | ||||
|      * | ||||
|      * @param request that an authentication request is being created for | ||||
|      * @param authRequest the authentication request object that should have | ||||
|      *        its details set | ||||
|      * @return the default | ||||
|      */ | ||||
|     protected void setDetails(HttpServletRequest request, | ||||
|         UsernamePasswordAuthenticationToken authRequest) { | ||||
|         authRequest.setDetails(new WebAuthenticationDetails(request, false)); | ||||
|     public String getDefaultFilterProcessesUrl() { | ||||
|         return "/j_acegi_security_check"; | ||||
|     } | ||||
| 
 | ||||
|     public void init(FilterConfig filterConfig) throws ServletException {} | ||||
| 
 | ||||
|     /** | ||||
|      * Enables subclasses to override the composition of the password, such as | ||||
|      * by including additional values and a separator. | ||||
| @ -141,4 +128,17 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { | ||||
|     protected String obtainUsername(HttpServletRequest request) { | ||||
|         return request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Provided so that subclasses may configure what is put into the | ||||
|      * authentication request's details property. | ||||
|      * | ||||
|      * @param request that an authentication request is being created for | ||||
|      * @param authRequest the authentication request object that should have | ||||
|      *        its details set | ||||
|      */ | ||||
|     protected void setDetails(HttpServletRequest request, | ||||
|         UsernamePasswordAuthenticationToken authRequest) { | ||||
|         authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* Copyright 2004, 2005 Acegi Technology Pty Limited | ||||
| /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -18,19 +18,24 @@ package org.acegisecurity.ui.x509; | ||||
| import org.acegisecurity.Authentication; | ||||
| import org.acegisecurity.AuthenticationException; | ||||
| import org.acegisecurity.AuthenticationManager; | ||||
| 
 | ||||
| import org.acegisecurity.context.SecurityContextHolder; | ||||
| 
 | ||||
| import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent; | ||||
| 
 | ||||
| import org.acegisecurity.providers.x509.X509AuthenticationToken; | ||||
| 
 | ||||
| import org.acegisecurity.ui.AbstractProcessingFilter; | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSource; | ||||
| import org.acegisecurity.ui.AuthenticationDetailsSourceImpl; | ||||
| 
 | ||||
| import org.apache.commons.logging.Log; | ||||
| import org.apache.commons.logging.LogFactory; | ||||
| 
 | ||||
| import org.springframework.beans.factory.InitializingBean; | ||||
| 
 | ||||
| import org.springframework.context.ApplicationEventPublisherAware; | ||||
| import org.springframework.context.ApplicationEventPublisher; | ||||
| import org.springframework.context.ApplicationEventPublisherAware; | ||||
| 
 | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| @ -60,10 +65,11 @@ import javax.servlet.http.HttpServletResponse; | ||||
|  *  | ||||
|  * <p> | ||||
|  * If authentication is successful, an {@link | ||||
|  * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be | ||||
|  * published to the application context. No events will be published if | ||||
|  * authentication was unsuccessful, because this would generally be recorded | ||||
|  * via an <code>AuthenticationManager</code>-specific application event. | ||||
|  * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} | ||||
|  * will be published to the application context. No events will be published | ||||
|  * if authentication was unsuccessful, because this would generally be | ||||
|  * recorded via an <code>AuthenticationManager</code>-specific application | ||||
|  * event. | ||||
|  * </p> | ||||
|  *  | ||||
|  * <p> | ||||
| @ -76,7 +82,7 @@ import javax.servlet.http.HttpServletResponse; | ||||
|  * @version $Id$ | ||||
|  */ | ||||
| public class X509ProcessingFilter implements Filter, InitializingBean, | ||||
|         ApplicationEventPublisherAware { | ||||
|     ApplicationEventPublisherAware { | ||||
|     //~ Static fields/initializers ============================================= | ||||
| 
 | ||||
|     private static final Log logger = LogFactory.getLog(X509ProcessingFilter.class); | ||||
| @ -84,19 +90,11 @@ public class X509ProcessingFilter implements Filter, InitializingBean, | ||||
|     //~ Instance fields ======================================================== | ||||
| 
 | ||||
|     private ApplicationEventPublisher eventPublisher; | ||||
|     private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); | ||||
|     private AuthenticationManager authenticationManager; | ||||
| 
 | ||||
|     //~ Methods ================================================================ | ||||
| 
 | ||||
|     public void setApplicationEventPublisher(ApplicationEventPublisher context) { | ||||
|         this.eventPublisher = context; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthenticationManager( | ||||
|         AuthenticationManager authenticationManager) { | ||||
|         this.authenticationManager = authenticationManager; | ||||
|     } | ||||
| 
 | ||||
|     public void afterPropertiesSet() throws Exception { | ||||
|         Assert.notNull(authenticationManager, | ||||
|             "An AuthenticationManager must be set"); | ||||
| @ -154,7 +152,8 @@ public class X509ProcessingFilter implements Filter, InitializingBean, | ||||
|             try { | ||||
|                 X509AuthenticationToken authRequest = new X509AuthenticationToken(clientCertificate); | ||||
| 
 | ||||
|                 authRequest.setDetails(new WebAuthenticationDetails(httpRequest)); | ||||
|                 authRequest.setDetails(authenticationDetailsSource.buildDetails( | ||||
|                         (HttpServletRequest) request)); | ||||
|                 authResult = authenticationManager.authenticate(authRequest); | ||||
|                 successfulAuthentication(httpRequest, httpResponse, authResult); | ||||
|             } catch (AuthenticationException failed) { | ||||
| @ -165,8 +164,39 @@ public class X509ProcessingFilter implements Filter, InitializingBean, | ||||
|         filterChain.doFilter(request, response); | ||||
|     } | ||||
| 
 | ||||
|     private X509Certificate extractClientCertificate(HttpServletRequest request) { | ||||
|         X509Certificate[] certs = (X509Certificate[]) request.getAttribute( | ||||
|                 "javax.servlet.request.X509Certificate"); | ||||
| 
 | ||||
|         if ((certs != null) && (certs.length > 0)) { | ||||
|             return certs[0]; | ||||
|         } | ||||
| 
 | ||||
|         if (logger.isDebugEnabled()) { | ||||
|             logger.debug("No client certificate found in request."); | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     public void init(FilterConfig ignored) throws ServletException {} | ||||
| 
 | ||||
|     public void setApplicationEventPublisher(ApplicationEventPublisher context) { | ||||
|         this.eventPublisher = context; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthenticationDetailsSource( | ||||
|         AuthenticationDetailsSource authenticationDetailsSource) { | ||||
|         Assert.notNull(authenticationDetailsSource, | ||||
|             "AuthenticationDetailsSource required"); | ||||
|         this.authenticationDetailsSource = authenticationDetailsSource; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthenticationManager( | ||||
|         AuthenticationManager authenticationManager) { | ||||
|         this.authenticationManager = authenticationManager; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Puts the <code>Authentication</code> instance returned by the | ||||
|      * authentication manager into the secure context. | ||||
| @ -206,25 +236,12 @@ public class X509ProcessingFilter implements Filter, InitializingBean, | ||||
|         SecurityContextHolder.getContext().setAuthentication(null); | ||||
| 
 | ||||
|         if (logger.isDebugEnabled()) { | ||||
|             logger.debug("Updated SecurityContextHolder to contain null Authentication"); | ||||
|             logger.debug( | ||||
|                 "Updated SecurityContextHolder to contain null Authentication"); | ||||
|         } | ||||
| 
 | ||||
|         request.getSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, | ||||
|         request.getSession() | ||||
|                .setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, | ||||
|             failed); | ||||
|     } | ||||
| 
 | ||||
|     private X509Certificate extractClientCertificate(HttpServletRequest request) { | ||||
|         X509Certificate[] certs = (X509Certificate[]) request.getAttribute( | ||||
|                 "javax.servlet.request.X509Certificate"); | ||||
| 
 | ||||
|         if ((certs != null) && (certs.length > 0)) { | ||||
|             return certs[0]; | ||||
|         } | ||||
| 
 | ||||
|         if (logger.isDebugEnabled()) { | ||||
|             logger.debug("No client certificate found in request."); | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* Copyright 2004, 2005 Acegi Technology Pty Limited | ||||
| /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -18,8 +18,11 @@ package org.acegisecurity.concurrent; | ||||
| import junit.framework.TestCase; | ||||
| 
 | ||||
| import org.acegisecurity.Authentication; | ||||
| 
 | ||||
| import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; | ||||
| 
 | ||||
| import org.acegisecurity.ui.WebAuthenticationDetails; | ||||
| 
 | ||||
| import org.springframework.mock.web.MockHttpServletRequest; | ||||
| import org.springframework.mock.web.MockHttpSession; | ||||
| 
 | ||||
| @ -33,6 +36,23 @@ import org.springframework.mock.web.MockHttpSession; | ||||
| public class ConcurrentSessionControllerImplTests extends TestCase { | ||||
|     //~ Methods ================================================================ | ||||
| 
 | ||||
|     private Authentication createAuthentication(String user, String password) { | ||||
|         UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, | ||||
|                 password); | ||||
|         auth.setDetails(createWebDetails(auth)); | ||||
| 
 | ||||
|         return auth; | ||||
|     } | ||||
| 
 | ||||
|     private WebAuthenticationDetails createWebDetails(Authentication auth) { | ||||
|         MockHttpSession session = new MockHttpSession(); | ||||
|         MockHttpServletRequest request = new MockHttpServletRequest(); | ||||
|         request.setSession(session); | ||||
|         request.setUserPrincipal(auth); | ||||
| 
 | ||||
|         return new WebAuthenticationDetails(request); | ||||
|     } | ||||
| 
 | ||||
|     public void testLifecycle() throws Exception { | ||||
|         // Build a test fixture | ||||
|         ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl(); | ||||
| @ -103,21 +123,4 @@ public class ConcurrentSessionControllerImplTests extends TestCase { | ||||
|             assertTrue(true); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private Authentication createAuthentication(String user, String password) { | ||||
|         UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, | ||||
|                 password); | ||||
|         auth.setDetails(createWebDetails(auth)); | ||||
| 
 | ||||
|         return auth; | ||||
|     } | ||||
| 
 | ||||
|     private WebAuthenticationDetails createWebDetails(Authentication auth) { | ||||
|         MockHttpSession session = new MockHttpSession(); | ||||
|         MockHttpServletRequest request = new MockHttpServletRequest(); | ||||
|         request.setSession(session); | ||||
|         request.setUserPrincipal(auth); | ||||
| 
 | ||||
|         return new WebAuthenticationDetails(request, false); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user