1
0
mirror of synced 2026-05-22 21:33:16 +00:00

SEC-674: Created new project modules for cas, captcha, acls and taglibs

This commit is contained in:
Luke Taylor
2008-02-19 20:30:53 +00:00
parent 59651f5214
commit 2dd9faabc0
149 changed files with 425 additions and 218 deletions
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>spring-security-cas</artifactId>
<groupId>org.springframework.security</groupId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas-client</artifactId>
<name>Spring Security - CAS Client Integration</name>
<version>2.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,208 @@
/* 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.springframework.security.providers.cas;
import org.springframework.security.SpringSecurityMessageSource;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.providers.AuthenticationProvider;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.providers.cas.cache.NullStatelessTicketCache;
import org.springframework.security.ui.cas.CasProcessingFilter;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UserDetailsChecker;
import org.springframework.security.userdetails.checker.AccountStatusUserDetailsChecker;
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;
/**
* An {@link AuthenticationProvider} implementation that integrates with JA-SIG Central Authentication Service
* (CAS).
* <p>
* This <code>AuthenticationProvider</code> is capable of validating {@link UsernamePasswordAuthenticationToken}
* requests which contain a <code>principal</code> name equal to either
* {@link CasProcessingFilter#CAS_STATEFUL_IDENTIFIER} or {@link CasProcessingFilter#CAS_STATELESS_IDENTIFIER}.
* It can also validate a previously created {@link CasAuthenticationToken}.
*
* @author Ben Alex
* @version $Id$
*/
public class CasAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class);
//~ Instance fields ================================================================================================
private UserDetailsService userDetailsService;
private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
private CasProxyDecider casProxyDecider;
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private StatelessTicketCache statelessTicketCache = new NullStatelessTicketCache();
private String key;
private TicketValidator ticketValidator;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.userDetailsService, "A userDetailsService must be set");
Assert.notNull(this.ticketValidator, "A ticketValidator must be set");
Assert.notNull(this.casProxyDecider, "A casProxyDecider must be set");
Assert.notNull(this.statelessTicketCache, "A statelessTicketCache must be set");
Assert.hasText(this.key, "A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated");
Assert.notNull(this.messages, "A message source must be set");
}
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (!supports(authentication.getClass())) {
return null;
}
if (authentication instanceof UsernamePasswordAuthenticationToken
&& (!CasProcessingFilter.CAS_STATEFUL_IDENTIFIER.equals(authentication.getPrincipal().toString())
&& !CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals(authentication.getPrincipal().toString()))) {
// UsernamePasswordAuthenticationToken not CAS related
return null;
}
// If an existing CasAuthenticationToken, just check we created it
if (authentication instanceof CasAuthenticationToken) {
if (this.key.hashCode() == ((CasAuthenticationToken) authentication).getKeyHash()) {
return authentication;
} else {
throw new BadCredentialsException(messages.getMessage("CasAuthenticationProvider.incorrectKey",
"The presented CasAuthenticationToken does not contain the expected key"));
}
}
// Ensure credentials are presented
if ((authentication.getCredentials() == null) || "".equals(authentication.getCredentials())) {
throw new BadCredentialsException(messages.getMessage("CasAuthenticationProvider.noServiceTicket",
"Failed to provide a CAS service ticket to validate"));
}
boolean stateless = false;
if (authentication instanceof UsernamePasswordAuthenticationToken
&& CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals(authentication.getPrincipal())) {
stateless = true;
}
CasAuthenticationToken result = null;
if (stateless) {
// Try to obtain from cache
result = statelessTicketCache.getByTicketId(authentication.getCredentials().toString());
}
if (result == null) {
result = this.authenticateNow(authentication);
result.setDetails(authentication.getDetails());
}
if (stateless) {
// Add to cache
statelessTicketCache.putTicketInCache(result);
}
return result;
}
private CasAuthenticationToken authenticateNow(Authentication authentication) throws AuthenticationException {
// Validate
TicketResponse response = ticketValidator.confirmTicketValid(authentication.getCredentials().toString());
// Check proxy list is trusted
this.casProxyDecider.confirmProxyListTrusted(response.getProxyList());
// Lookup user details
UserDetails userDetails = userDetailsService.loadUserByUsername(response.getUser());
userDetailsChecker.check(userDetails);
// Construct CasAuthenticationToken
return new CasAuthenticationToken(this.key, userDetails, authentication.getCredentials(),
userDetails.getAuthorities(), userDetails, response.getProxyList(), response.getProxyGrantingTicketIou());
}
protected UserDetailsService getUserDetailsService() {
return userDetailsService;
}
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
public CasProxyDecider getCasProxyDecider() {
return casProxyDecider;
}
public void setCasProxyDecider(CasProxyDecider casProxyDecider) {
this.casProxyDecider = casProxyDecider;
}
protected String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public StatelessTicketCache getStatelessTicketCache() {
return statelessTicketCache;
}
protected TicketValidator getTicketValidator() {
return ticketValidator;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setStatelessTicketCache(StatelessTicketCache statelessTicketCache) {
this.statelessTicketCache = statelessTicketCache;
}
public void setTicketValidator(TicketValidator ticketValidator) {
this.ticketValidator = ticketValidator;
}
public boolean supports(Class authentication) {
if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)) {
return true;
} else if (CasAuthenticationToken.class.isAssignableFrom(authentication)) {
return true;
} else {
return false;
}
}
}
@@ -0,0 +1,157 @@
/* 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.springframework.security.providers.cas;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.providers.AbstractAuthenticationToken;
import org.springframework.security.userdetails.UserDetails;
import java.io.Serializable;
import java.util.List;
/**
* Represents a successful CAS <code>Authentication</code>.
*
* @author Ben Alex
* @version $Id$
*/
public class CasAuthenticationToken extends AbstractAuthenticationToken implements Serializable {
//~ Instance fields ================================================================================================
private static final long serialVersionUID = 1L;
private final List proxyList;
private final Object credentials;
private final Object principal;
private final String proxyGrantingTicketIou;
private final UserDetails userDetails;
private final int keyHash;
//~ Constructors ===================================================================================================
/**
* Constructor.
*
* @param key to identify if this object made by a given {@link
* CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param credentials the service/proxy ticket ID from CAS (cannot be
* <code>null</code>)
* @param authorities the authorities granted to the user (from the {@link
* org.springframework.security.userdetails.UserDetailsService}) (cannot be <code>null</code>)
* @param userDetails the user details (from the {@link
* org.springframework.security.userdetails.UserDetailsService}) (cannot be <code>null</code>)
* @param proxyList the list of proxies from CAS (cannot be
* <code>null</code>)
* @param proxyGrantingTicketIou the PGT-IOU ID from CAS (cannot be
* <code>null</code>, but may be an empty <code>String</code> if no
* PGT-IOU ID was provided)
*
* @throws IllegalArgumentException if a <code>null</code> was passed
*/
public CasAuthenticationToken(final String key, final Object principal, final Object credentials,
final GrantedAuthority[] authorities, final UserDetails userDetails, final List proxyList,
final String proxyGrantingTicketIou) {
super(authorities);
if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal) || (credentials == null)
|| "".equals(credentials) || (authorities == null) || (userDetails == null) || (proxyList == null)
|| (proxyGrantingTicketIou == null)) {
throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
}
this.keyHash = key.hashCode();
this.principal = principal;
this.credentials = credentials;
this.userDetails = userDetails;
this.proxyList = proxyList;
this.proxyGrantingTicketIou = proxyGrantingTicketIou;
setAuthenticated(true);
}
//~ Methods ========================================================================================================
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
if (obj instanceof CasAuthenticationToken) {
CasAuthenticationToken test = (CasAuthenticationToken) obj;
// proxyGrantingTicketIou is never null due to constructor
if (!this.getProxyGrantingTicketIou().equals(test.getProxyGrantingTicketIou())) {
return false;
}
// proxyList is never null due to constructor
if (!this.getProxyList().equals(test.getProxyList())) {
return false;
}
if (this.getKeyHash() != test.getKeyHash()) {
return false;
}
return true;
}
return false;
}
public Object getCredentials() {
return this.credentials;
}
public int getKeyHash() {
return this.keyHash;
}
public Object getPrincipal() {
return this.principal;
}
/**
* Obtains the proxy granting ticket IOU.
*
* @return the PGT IOU-ID or an empty <code>String</code> if no proxy callback was requested when validating the
* service ticket
*/
public String getProxyGrantingTicketIou() {
return proxyGrantingTicketIou;
}
public List getProxyList() {
return proxyList;
}
public UserDetails getUserDetails() {
return userDetails;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString());
sb.append("; Credentials (Service/Proxy Ticket): ").append(this.credentials);
sb.append("; Proxy-Granting Ticket IOU: ").append(this.proxyGrantingTicketIou);
sb.append("; Proxy List: ").append(this.proxyList);
return (sb.toString());
}
}
@@ -0,0 +1,73 @@
/* 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.springframework.security.providers.cas;
import java.util.List;
/**
* Decides whether a proxy list presented via CAS is trusted or not.
*
* <p>
* CAS 1.0 allowed services to receive a service ticket and then validate it.
* CAS 2.0 allows services to receive a service ticket and then validate it
* with a proxy callback URL. The callback will enable the CAS server to
* authenticate the service. In doing so the service will receive a
* proxy-granting ticket and a proxy-granting ticket IOU. The IOU is just an
* internal record that a proxy-granting ticket is due to be received via the
* callback URL.
* </p>
*
* <p>
* With a proxy-granting ticket, a service can request the CAS server provides
* it with a proxy ticket. A proxy ticket is just a service ticket, but the
* CAS server internally tracks the list (chain) of services used to build the
* proxy ticket. The proxy ticket is then presented to the target service.
* </p>
*
* <p>
* If this application is a target service of a proxy ticket, the
* <code>CasProxyDecider</code> resolves whether or not the proxy list is
* trusted. Applications should only trust services they allow to impersonate
* an end user.
* </p>
*
* <p>
* If this application is a service that should never accept proxy-granting
* tickets, the implementation should reject tickets that present a proxy list
* with any members. If the list has no members, it indicates the CAS server
* directly authenticated the user (ie there are no services which proxied the
* user authentication).
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public interface CasProxyDecider {
//~ Methods ========================================================================================================
/**
* Decides whether the proxy list is trusted.
* <p>Must throw any <code>ProxyUntrustedException</code> if the
* proxy list is untrusted.</p>
*
* @param proxyList the list of proxies to be checked.
*
* @throws ProxyUntrustedException DOCUMENT ME!
*/
void confirmProxyListTrusted(List proxyList)
throws ProxyUntrustedException;
}
@@ -0,0 +1,50 @@
/* 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.springframework.security.providers.cas;
import org.springframework.security.AuthenticationException;
/**
* Thrown if a CAS proxy ticket is presented from an untrusted proxy.
*
* @author Ben Alex
* @version $Id$
*/
public class ProxyUntrustedException extends AuthenticationException {
//~ Constructors ===================================================================================================
/**
* Constructs a <code>ProxyUntrustedException</code> with the specified
* message.
*
* @param msg the detail message.
*/
public ProxyUntrustedException(String msg) {
super(msg);
}
/**
* Constructs a <code>ProxyUntrustedException</code> with the specified
* message and root cause.
*
* @param msg the detail message.
* @param t root cause
*/
public ProxyUntrustedException(String msg, Throwable t) {
super(msg, t);
}
}
@@ -0,0 +1,116 @@
/* Copyright 2004 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.springframework.security.providers.cas;
/**
* Caches CAS service tickets and CAS proxy tickets for stateless connections.
*
* <p>
* When a service ticket or proxy ticket is validated against the CAS server,
* it is unable to be used again. Most types of callers are stateful and are
* associated with a given <code>HttpSession</code>. This allows the
* affirmative CAS validation outcome to be stored in the
* <code>HttpSession</code>, meaning the removal of the ticket from the CAS
* server is not an issue.
* </p>
*
* <P>
* Stateless callers, such as remoting protocols, cannot take advantage of
* <code>HttpSession</code>. If the stateless caller is located a significant
* network distance from the CAS server, acquiring a fresh service ticket or
* proxy ticket for each invocation would be expensive.
* </p>
*
* <P>
* To avoid this issue with stateless callers, it is expected stateless callers
* will obtain a single service ticket or proxy ticket, and then present this
* same ticket to the Spring Security secured application on each
* occasion. As no <code>HttpSession</code> is available for such callers, the
* affirmative CAS validation outcome cannot be stored in this location.
* </p>
*
* <P>
* The <code>StatelessTicketCache</code> enables the service tickets and proxy
* tickets belonging to stateless callers to be placed in a cache. This
* in-memory cache stores the <code>CasAuthenticationToken</code>, effectively
* providing the same capability as a <code>HttpSession</code> with the ticket
* identifier being the key rather than a session identifier.
* </p>
*
* <P>
* Implementations should provide a reasonable timeout on stored entries, such
* that the stateless caller are not required to unnecessarily acquire fresh
* CAS service tickets or proxy tickets.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public interface StatelessTicketCache {
//~ Methods ================================================================
/**
* Retrieves the <code>CasAuthenticationToken</code> associated with the
* specified ticket.
*
* <P>
* If not found, returns a
* <code>null</code><code>CasAuthenticationToken</code>.
* </p>
*
* @return the fully populated authentication token
*/
CasAuthenticationToken getByTicketId(String serviceTicket);
/**
* Adds the specified <code>CasAuthenticationToken</code> to the cache.
*
* <P>
* The {@link CasAuthenticationToken#getCredentials()} method is used to
* retrieve the service ticket number.
* </p>
*
* @param token to be added to the cache
*/
void putTicketInCache(CasAuthenticationToken token);
/**
* Removes the specified ticket from the cache, as per {@link
* #removeTicketFromCache(String)}.
*
* <P>
* Implementations should use {@link
* CasAuthenticationToken#getCredentials()} to obtain the ticket and then
* delegate to to the {@link #removeTicketFromCache(String)} method.
* </p>
*
* @param token to be removed
*/
void removeTicketFromCache(CasAuthenticationToken token);
/**
* Removes the specified ticket from the cache, meaning that future calls
* will require a new service ticket.
*
* <P>
* This is in case applications wish to provide a session termination
* capability for their stateless clients.
* </p>
*
* @param serviceTicket to be removed
*/
void removeTicketFromCache(String serviceTicket);
}
@@ -0,0 +1,96 @@
/* 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.springframework.security.providers.cas;
import java.util.List;
import java.util.Vector;
/**
* Represents a CAS service ticket in native CAS form.
*
* @author Ben Alex
* @version $Id$
*/
public class TicketResponse {
//~ Instance fields ================================================================================================
private List proxyList;
private String proxyGrantingTicketIou;
private String user;
//~ Constructors ===================================================================================================
/**
* Constructor.
*
* <P>
* If <code>null</code> is passed into the <code>proxyList</code> or
* <code>proxyGrantingTicketIou</code>, suitable defaults are established.
* However, <code>null</code> cannot be passed for the <code>user</code>
* argument.
* </p>
*
* @param user the user as indicated by CAS (cannot be <code>null</code> or
* an empty <code>String</code>)
* @param proxyList as provided by CAS (may be <code>null</code>)
* @param proxyGrantingTicketIou as provided by CAS (may be
* <code>null</code>)
*
* @throws IllegalArgumentException DOCUMENT ME!
*/
public TicketResponse(String user, List proxyList, String proxyGrantingTicketIou) {
if (proxyList == null) {
proxyList = new Vector();
}
if (proxyGrantingTicketIou == null) {
proxyGrantingTicketIou = "";
}
if ((user == null) || "".equals(user)) {
throw new IllegalArgumentException("Cannot pass null or empty String for User");
}
this.user = user;
this.proxyList = proxyList;
this.proxyGrantingTicketIou = proxyGrantingTicketIou;
}
//~ Methods ========================================================================================================
public String getProxyGrantingTicketIou() {
return proxyGrantingTicketIou;
}
public List getProxyList() {
return proxyList;
}
public String getUser() {
return user;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString());
sb.append(": User: " + this.user);
sb.append("; Proxy-Granting Ticket IOU: " + this.proxyGrantingTicketIou);
sb.append("; Proxy List: " + this.proxyList.toString());
return sb.toString();
}
}
@@ -0,0 +1,53 @@
/* 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.springframework.security.providers.cas;
import org.springframework.security.AuthenticationException;
/**
* Validates a CAS service ticket.
*
* <p>
* Implementations must accept CAS proxy tickets, in addition to CAS service
* tickets. If proxy tickets should be rejected, this is resolved by a {@link
* CasProxyDecider} implementation (not by the <code>TicketValidator</code>).
* </p>
*
* <p>
* Implementations may request a proxy granting ticket if wish, although this
* behaviour is not mandatory.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public interface TicketValidator {
//~ Methods ========================================================================================================
/**
* Returns information about the ticket, if it is valid for this service.<P>Must throw an
* <code>AuthenticationException</code> if the ticket is not valid for this service.</p>
*
* @param serviceTicket DOCUMENT ME!
*
* @return details of the CAS service ticket
*
* @throws AuthenticationException DOCUMENT ME!
*/
TicketResponse confirmTicketValid(String serviceTicket)
throws AuthenticationException;
}
@@ -0,0 +1,105 @@
/* 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.springframework.security.providers.cas.cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Element;
import net.sf.ehcache.Ehcache;
import org.springframework.security.providers.cas.CasAuthenticationToken;
import org.springframework.security.providers.cas.StatelessTicketCache;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.util.Assert;
/**
* Caches tickets using a Spring IoC defined <A HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
*
* @author Ben Alex
* @version $Id$
*/
public class EhCacheBasedTicketCache implements StatelessTicketCache, InitializingBean {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(EhCacheBasedTicketCache.class);
//~ Instance fields ================================================================================================
private Ehcache cache;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "cache mandatory");
}
public CasAuthenticationToken getByTicketId(String serviceTicket) {
Element element = null;
try {
element = cache.get(serviceTicket);
} catch (CacheException cacheException) {
throw new DataRetrievalFailureException("Cache failure: " + cacheException.getMessage());
}
if (logger.isDebugEnabled()) {
logger.debug("Cache hit: " + (element != null) + "; service ticket: " + serviceTicket);
}
if (element == null) {
return null;
} else {
return (CasAuthenticationToken) element.getValue();
}
}
public Ehcache getCache() {
return cache;
}
public void putTicketInCache(CasAuthenticationToken token) {
Element element = new Element(token.getCredentials().toString(), token);
if (logger.isDebugEnabled()) {
logger.debug("Cache put: " + element.getKey());
}
cache.put(element);
}
public void removeTicketFromCache(CasAuthenticationToken token) {
if (logger.isDebugEnabled()) {
logger.debug("Cache remove: " + token.getCredentials().toString());
}
this.removeTicketFromCache(token.getCredentials().toString());
}
public void removeTicketFromCache(String serviceTicket) {
cache.remove(serviceTicket);
}
public void setCache(Ehcache cache) {
this.cache = cache;
}
}
@@ -0,0 +1,63 @@
/* 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.springframework.security.providers.cas.cache;
import org.springframework.security.providers.cas.CasAuthenticationProvider;
import org.springframework.security.providers.cas.CasAuthenticationToken;
import org.springframework.security.providers.cas.StatelessTicketCache;
/**
* Implementation of @link {@link StatelessTicketCache} that has no backing cache. Useful
* in instances where storing of tickets for stateless session management is not required.
* <p>
* This is the default StatelessTicketCache of the @link {@link CasAuthenticationProvider} to
* eliminate the unnecessary dependency on EhCache that applications have even if they are not using
* the stateless session management.
*
* @author Scott Battaglia
* @version $Id$
*
*@see CasAuthenticationProvider
*/
public final class NullStatelessTicketCache implements StatelessTicketCache {
/**
* @return null since we are not storing any tickets.
*/
public CasAuthenticationToken getByTicketId(final String serviceTicket) {
return null;
}
/**
* This is a no-op since we are not storing tickets.
*/
public void putTicketInCache(final CasAuthenticationToken token) {
// nothing to do
}
/**
* This is a no-op since we are not storing tickets.
*/
public void removeTicketFromCache(final CasAuthenticationToken token) {
// nothing to do
}
/**
* This is a no-op since we are not storing tickets.
*/
public void removeTicketFromCache(final String serviceTicket) {
// nothing to do
}
}
@@ -0,0 +1,5 @@
<html>
<body>
Caches CAS tickets for the <code>CasAuthenticationProvider</code>.
</body>
</html>
@@ -0,0 +1,6 @@
<html>
<body>
An authentication provider that can process JA-SIG Central Authentication Service (CAS)
service tickets and proxy tickets.
</body>
</html>
@@ -0,0 +1,51 @@
/* 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.springframework.security.providers.cas.proxy;
import org.springframework.security.providers.cas.CasProxyDecider;
import org.springframework.security.providers.cas.ProxyUntrustedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import java.util.List;
/**
* Accepts a proxied request from any other service.<P>Also accepts the request if there was no proxy (ie the user
* directly authenticated against this service).</p>
*
* @author Ben Alex
* @version $Id$
*/
public class AcceptAnyCasProxy implements CasProxyDecider {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(AcceptAnyCasProxy.class);
//~ Methods ========================================================================================================
public void confirmProxyListTrusted(List proxyList)
throws ProxyUntrustedException {
Assert.notNull(proxyList, "proxyList cannot be null");
if (logger.isDebugEnabled()) {
logger.debug("Always accepting proxy list: " + proxyList.toString());
}
}
}
@@ -0,0 +1,88 @@
/* 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.springframework.security.providers.cas.proxy;
import org.springframework.security.SpringSecurityMessageSource;
import org.springframework.security.providers.cas.CasProxyDecider;
import org.springframework.security.providers.cas.ProxyUntrustedException;
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 java.util.List;
/**
* Accepts proxied requests if the closest proxy is named in the <code>validProxies</code> list.<P>Also accepts the
* request if there was no proxy (ie the user directly authenticated against this service).</p>
*/
public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean, MessageSourceAware {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(NamedCasProxyDecider.class);
//~ Instance fields ================================================================================================
private List validProxies;
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.validProxies, "A validProxies list must be set");
Assert.notNull(this.messages, "A message source must be set");
}
public void confirmProxyListTrusted(List proxyList)
throws ProxyUntrustedException {
Assert.notNull(proxyList, "proxyList cannot be null");
if (logger.isDebugEnabled()) {
logger.debug("Proxy list: " + proxyList.toString());
}
if (proxyList.size() == 0) {
// A Service Ticket (not a Proxy Ticket)
return;
}
if (!validProxies.contains(proxyList.get(0))) {
throw new ProxyUntrustedException(messages.getMessage("NamedCasProxyDecider.untrusted",
new Object[] {proxyList.get(0)}, "Nearest proxy {0} is untrusted"));
}
}
public List getValidProxies() {
return validProxies;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setValidProxies(List validProxies) {
this.validProxies = validProxies;
}
}
@@ -0,0 +1,76 @@
/* 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.springframework.security.providers.cas.proxy;
import org.springframework.security.SpringSecurityMessageSource;
import org.springframework.security.providers.cas.CasProxyDecider;
import org.springframework.security.providers.cas.ProxyUntrustedException;
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 java.util.List;
/**
* Accepts no proxied requests.<P>This class should be used if only service tickets wish to be accepted (ie no
* proxy tickets at all).</p>
*/
public class RejectProxyTickets implements CasProxyDecider, MessageSourceAware, InitializingBean {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(RejectProxyTickets.class);
//~ Instance fields ================================================================================================
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.messages, "A message source must be set");
}
public void confirmProxyListTrusted(List proxyList)
throws ProxyUntrustedException {
Assert.notNull(proxyList, "proxyList cannot be null");
if (proxyList.size() == 0) {
// A Service Ticket (not a Proxy Ticket)
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Proxies are unacceptable; proxy list provided: " + proxyList.toString());
}
throw new ProxyUntrustedException(
messages.getMessage("RejectProxyTickets.reject", "Proxy tickets are rejected"));
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
}
@@ -0,0 +1,6 @@
<html>
<body>
Implementations that decide whether proxy lists of
CAS authentications are trusted.
</body>
</html>
@@ -0,0 +1,114 @@
/* 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.springframework.security.providers.cas.ticketvalidator;
import org.springframework.security.providers.cas.TicketValidator;
import org.springframework.security.ui.cas.ServiceProperties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.io.File;
/**
* Convenience abstract base for <code>TicketValidator</code>s.
*
* @author Ben Alex
* @version $Id$
*/
public abstract class AbstractTicketValidator implements TicketValidator, InitializingBean {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(AbstractTicketValidator.class);
//~ Instance fields ================================================================================================
private ServiceProperties serviceProperties;
private String casValidate;
private String trustStore;
private String trustPassword;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.hasLength(casValidate, "A casValidate URL must be set");
Assert.notNull(serviceProperties, "serviceProperties must be specified");
if (StringUtils.hasLength(trustStore)) {
logger.info("Setting system property 'javax.net.ssl.trustStore' to value [" + trustStore + "]");
if (! (new File(trustStore)).exists()) {
throw new IllegalArgumentException("Parameter 'trustStore' file does not exist at " + trustStore);
}
System.setProperty("javax.net.ssl.trustStore", trustStore);
}
if (StringUtils.hasLength(trustPassword)) {
System.setProperty("javax.net.ssl.trustStorePassword", trustPassword);
}
}
/**
* Mandatory URL to CAS' proxy ticket valiation service.<P>This is usually something like
* <code>https://www.mycompany.com/cas/proxyValidate</code>.</p>
*
* @return the CAS proxy ticket validation URL
*/
public String getCasValidate() {
return casValidate;
}
public ServiceProperties getServiceProperties() {
return serviceProperties;
}
/**
* Optional property which will be used to set the system property <code>javax.net.ssl.trustStore</code>.
*
* @return the <code>javax.net.ssl.trustStore</code> that will be set during bean initialization, or
* <code>null</code> to leave the system property unchanged
*/
public String getTrustStore() {
return trustStore;
}
public void setCasValidate(String casValidate) {
this.casValidate = casValidate;
}
public void setServiceProperties(ServiceProperties serviceProperties) {
this.serviceProperties = serviceProperties;
}
public void setTrustStore(String trustStore) {
this.trustStore = trustStore;
}
/**
* Optional property which causes the system property <tt>javax.net.ssl.trustStorePassword</tt> to be set.
*
* @param trustPassword
*/
public void setTrustPassword(String trustPassword) {
this.trustPassword = trustPassword;
}
}
@@ -0,0 +1,116 @@
/* 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.springframework.security.providers.cas.ticketvalidator;
import edu.yale.its.tp.cas.client.ProxyTicketValidator;
import org.springframework.security.AuthenticationException;
import org.springframework.security.AuthenticationServiceException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.providers.cas.TicketResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Uses CAS' <code>ProxyTicketValidator</code> to validate a service ticket.
*
* @author Ben Alex
* @version $Id$
*/
public class CasProxyTicketValidator extends AbstractTicketValidator {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(CasProxyTicketValidator.class);
//~ Instance fields ================================================================================================
private String proxyCallbackUrl;
//~ Methods ========================================================================================================
public TicketResponse confirmTicketValid(String serviceTicket)
throws AuthenticationException {
// Attempt to validate presented ticket using CAS' ProxyTicketValidator class
ProxyTicketValidator pv = new ProxyTicketValidator();
pv.setCasValidateUrl(super.getCasValidate());
pv.setServiceTicket(serviceTicket);
pv.setService(super.getServiceProperties().getService());
if (super.getServiceProperties().isSendRenew()) {
logger.warn(
"The current CAS ProxyTicketValidator does not support the 'renew' property. "
+ "The ticket cannot be validated as having been issued by a 'renew' authentication. "
+ "It is expected this will be corrected in a future version of CAS' ProxyTicketValidator.");
}
if ((this.proxyCallbackUrl != null) && (!"".equals(this.proxyCallbackUrl))) {
pv.setProxyCallbackUrl(proxyCallbackUrl);
}
return validateNow(pv);
}
/**
* Optional callback URL to obtain a proxy-granting ticket from CAS.
* <p>This callback URL belongs to the Spring Security secured application. We suggest you use
* CAS' <code>ProxyTicketReceptor</code> servlet to receive this callback and manage the proxy-granting ticket list.
* The callback URL is usually something like
* <code>https://www.mycompany.com/application/casProxy/receptor</code>.
* </p>
* <p>If left <code>null</code>, the <code>CasAuthenticationToken</code> will not have a proxy granting
* ticket IOU and there will be no proxy-granting ticket callback. Accordingly, the Spring Securty
* secured application will be unable to obtain a proxy ticket to call another CAS-secured service on
* behalf of the user. This is not really an issue for most applications.</p>
*
* @return the proxy callback URL, or <code>null</code> if not used
*/
public String getProxyCallbackUrl() {
return proxyCallbackUrl;
}
public void setProxyCallbackUrl(String proxyCallbackUrl) {
this.proxyCallbackUrl = proxyCallbackUrl;
}
/**
* Perform the actual remote invocation. Protected to enable replacement during tests.
*
* @param pv the populated <code>ProxyTicketValidator</code>
*
* @return the <code>TicketResponse</code>
*
* @throws AuthenticationServiceException if<code>ProxyTicketValidator</code> internally fails
* @throws BadCredentialsException DOCUMENT ME!
*/
protected TicketResponse validateNow(ProxyTicketValidator pv)
throws AuthenticationServiceException, BadCredentialsException {
try {
pv.validate();
} catch (Exception internalProxyTicketValidatorProblem) {
throw new AuthenticationServiceException(internalProxyTicketValidatorProblem.getMessage());
}
if (!pv.isAuthenticationSuccesful()) {
throw new BadCredentialsException(pv.getErrorCode() + ": " + pv.getErrorMessage());
}
return new TicketResponse(pv.getUser(), pv.getProxyList(), pv.getPgtIou());
}
}
@@ -0,0 +1,5 @@
<html>
<body>
Implementations that validate service tickets.
</body>
</html>
@@ -0,0 +1,358 @@
/* 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.springframework.security.providers.cas;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.providers.cas.ticketvalidator.AbstractTicketValidator;
import org.springframework.security.ui.cas.CasProcessingFilter;
import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Tests {@link CasAuthenticationProvider}.
*
* @author Ben Alex
* @version $Id$
*/
public class CasAuthenticationProviderTests {
//~ Methods ========================================================================================================
private UserDetails makeUserDetails() {
return new User("user", "password", true, true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
}
private UserDetails makeUserDetailsFromAuthoritiesPopulator() {
return new User("user", "password", true, true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl("ROLE_B")});
}
@Test
public void statefulAuthenticationIsSuccessful() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
StatelessTicketCache cache = new MockStatelessTicketCache();
cap.setStatelessTicketCache(cache);
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(CasProcessingFilter.CAS_STATEFUL_IDENTIFIER,
"ST-123");
token.setDetails("details");
Authentication result = cap.authenticate(token);
// Confirm ST-123 was NOT added to the cache
assertTrue(cache.getByTicketId("ST-456") == null);
if (!(result instanceof CasAuthenticationToken)) {
fail("Should have returned a CasAuthenticationToken");
}
CasAuthenticationToken casResult = (CasAuthenticationToken) result;
assertEquals(makeUserDetailsFromAuthoritiesPopulator(), casResult.getPrincipal());
assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt",
casResult.getProxyGrantingTicketIou());
assertEquals("https://localhost/portal/j_spring_cas_security_check", casResult.getProxyList().get(0));
assertEquals("ST-123", casResult.getCredentials());
assertEquals(new GrantedAuthorityImpl("ROLE_A"), casResult.getAuthorities()[0]);
assertEquals(new GrantedAuthorityImpl("ROLE_B"), casResult.getAuthorities()[1]);
assertEquals(cap.getKey().hashCode(), casResult.getKeyHash());
assertEquals("details", casResult.getDetails());
// Now confirm the CasAuthenticationToken is automatically re-accepted.
// To ensure TicketValidator not called again, set it to deliver an exception...
cap.setTicketValidator(new MockTicketValidator(false));
Authentication laterResult = cap.authenticate(result);
assertEquals(result, laterResult);
}
@Test
public void statelessAuthenticationIsSuccessful() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
StatelessTicketCache cache = new MockStatelessTicketCache();
cap.setStatelessTicketCache(cache);
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(CasProcessingFilter.CAS_STATELESS_IDENTIFIER,
"ST-456");
token.setDetails("details");
Authentication result = cap.authenticate(token);
// Confirm ST-456 was added to the cache
assertTrue(cache.getByTicketId("ST-456") != null);
if (!(result instanceof CasAuthenticationToken)) {
fail("Should have returned a CasAuthenticationToken");
}
assertEquals(makeUserDetailsFromAuthoritiesPopulator(), result.getPrincipal());
assertEquals("ST-456", result.getCredentials());
assertEquals("details", result.getDetails());
// Now try to authenticate again. To ensure TicketValidator not
// called again, set it to deliver an exception...
cap.setTicketValidator(new MockTicketValidator(false));
// Previously created UsernamePasswordAuthenticationToken is OK
Authentication newResult = cap.authenticate(token);
assertEquals(makeUserDetailsFromAuthoritiesPopulator(), newResult.getPrincipal());
assertEquals("ST-456", newResult.getCredentials());
}
@Test(expected = BadCredentialsException.class)
public void missingTicketIdIsDetected() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
StatelessTicketCache cache = new MockStatelessTicketCache();
cap.setStatelessTicketCache(cache);
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
UsernamePasswordAuthenticationToken token =
new UsernamePasswordAuthenticationToken(CasProcessingFilter.CAS_STATEFUL_IDENTIFIER, "");
Authentication result = cap.authenticate(token);
}
@Test(expected = BadCredentialsException.class)
public void invalidKeyIsDetected() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
StatelessTicketCache cache = new MockStatelessTicketCache();
cap.setStatelessTicketCache(cache);
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
CasAuthenticationToken token = new CasAuthenticationToken("WRONG_KEY", makeUserDetails(), "credentials",
new GrantedAuthority[] {new GrantedAuthorityImpl("XX")}, makeUserDetails(), new Vector(), "IOU-xxx");
cap.authenticate(token);
}
@Test(expected = IllegalArgumentException.class)
public void detectsMissingAuthoritiesPopulator() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache());
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
}
@Test(expected = IllegalArgumentException.class)
public void detectsMissingKey() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setStatelessTicketCache(new MockStatelessTicketCache());
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
}
@Test(expected = IllegalArgumentException.class)
public void detectsMissingProxyDecider() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache());
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
}
@Test(expected = IllegalArgumentException.class)
public void detectsMissingStatelessTicketCache() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
// set this explicitly to null to test failure
cap.setStatelessTicketCache(null);
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
}
@Test(expected = IllegalArgumentException.class)
public void detectsMissingTicketValidator() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache());
cap.afterPropertiesSet();
}
@Test
public void gettersAndSettersMatch() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache());
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
assertTrue(cap.getUserDetailsService() != null);
assertTrue(cap.getCasProxyDecider() != null);
assertEquals("qwerty", cap.getKey());
assertTrue(cap.getStatelessTicketCache() != null);
assertTrue(cap.getTicketValidator() != null);
}
@Test
public void ignoresClassesItDoesNotSupport() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache());
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
TestingAuthenticationToken token = new TestingAuthenticationToken("user", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")});
assertFalse(cap.supports(TestingAuthenticationToken.class));
// Try it anyway
assertEquals(null, cap.authenticate(token));
}
@Test
public void ignoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setUserDetailsService(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache());
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("some_normal_user",
"password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")});
assertEquals(null, cap.authenticate(token));
}
@Test
public void supportsRequiredTokens() {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
assertTrue(cap.supports(UsernamePasswordAuthenticationToken.class));
assertTrue(cap.supports(CasAuthenticationToken.class));
}
//~ Inner Classes ==================================================================================================
private class MockAuthoritiesPopulator implements UserDetailsService {
public UserDetails loadUserByUsername(String casUserId) throws AuthenticationException {
return makeUserDetailsFromAuthoritiesPopulator();
}
}
private class MockProxyDecider implements CasProxyDecider {
private boolean acceptProxy;
public MockProxyDecider(boolean acceptProxy) {
this.acceptProxy = acceptProxy;
}
private MockProxyDecider() {
super();
}
public void confirmProxyListTrusted(List proxyList)
throws ProxyUntrustedException {
if (acceptProxy) {
return;
} else {
throw new ProxyUntrustedException("As requested from mock");
}
}
}
private class MockStatelessTicketCache implements StatelessTicketCache {
private Map cache = new HashMap();
public CasAuthenticationToken getByTicketId(String serviceTicket) {
return (CasAuthenticationToken) cache.get(serviceTicket);
}
public void putTicketInCache(CasAuthenticationToken token) {
cache.put(token.getCredentials().toString(), token);
}
public void removeTicketFromCache(CasAuthenticationToken token) {
throw new UnsupportedOperationException("mock method not implemented");
}
public void removeTicketFromCache(String serviceTicket) {
throw new UnsupportedOperationException("mock method not implemented");
}
}
private class MockTicketValidator extends AbstractTicketValidator {
private boolean returnTicket;
public MockTicketValidator(boolean returnTicket) {
this.returnTicket = returnTicket;
}
public TicketResponse confirmTicketValid(String serviceTicket)
throws AuthenticationException {
if (returnTicket) {
List list = new Vector();
list.add("https://localhost/portal/j_spring_cas_security_check");
return new TicketResponse("rod", list, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
}
throw new BadCredentialsException("As requested from mock");
}
}
}
@@ -0,0 +1,292 @@
/* 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.springframework.security.providers.cas;
import junit.framework.TestCase;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails;
import java.util.List;
import java.util.Vector;
/**
* Tests {@link CasAuthenticationToken}.
*
* @author Ben Alex
* @version $Id$
*/
public class CasAuthenticationTokenTests extends TestCase {
//~ Constructors ===================================================================================================
public CasAuthenticationTokenTests() {
super();
}
public CasAuthenticationTokenTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(CasAuthenticationTokenTests.class);
}
private UserDetails makeUserDetails() {
return makeUserDetails("user");
}
private UserDetails makeUserDetails(final String name) {
return new User(name, "password", true, true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
}
public final void setUp() throws Exception {
super.setUp();
}
public void testConstructorRejectsNulls() {
try {
new CasAuthenticationToken(null, makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new CasAuthenticationToken("key", null, "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new CasAuthenticationToken("key", makeUserDetails(), null,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new CasAuthenticationToken("key", makeUserDetails(), "Password", null, makeUserDetails(), new Vector(),
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), null, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
null, new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), new Vector(), null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), null, new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testEqualsWhenEqual() {
List proxyList1 = new Vector();
proxyList1.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
List proxyList2 = new Vector();
proxyList2.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token2 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList2, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertEquals(token1, token2);
}
public void testGetters() {
// Build the proxy list returned in the ticket from CAS
List proxyList = new Vector();
proxyList.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertEquals("key".hashCode(), token.getKeyHash());
assertEquals(makeUserDetails(), token.getPrincipal());
assertEquals("Password", token.getCredentials());
assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority());
assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority());
assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt", token.getProxyGrantingTicketIou());
assertEquals(proxyList, token.getProxyList());
assertEquals(makeUserDetails().getUsername(), token.getUserDetails().getUsername());
}
public void testNoArgConstructorDoesntExist() {
Class clazz = CasAuthenticationToken.class;
try {
clazz.getDeclaredConstructor((Class[]) null);
fail("Should have thrown NoSuchMethodException");
} catch (NoSuchMethodException expected) {
assertTrue(true);
}
}
public void testNotEqualsDueToAbstractParentEqualsCheck() {
List proxyList1 = new Vector();
proxyList1.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
List proxyList2 = new Vector();
proxyList2.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token2 = new CasAuthenticationToken("key", makeUserDetails("OTHER_NAME"), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList2, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertTrue(!token1.equals(token2));
}
public void testNotEqualsDueToDifferentAuthenticationClass() {
List proxyList1 = new Vector();
proxyList1.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
assertTrue(!token1.equals(token2));
}
public void testNotEqualsDueToKey() {
List proxyList1 = new Vector();
proxyList1.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
List proxyList2 = new Vector();
proxyList2.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token2 = new CasAuthenticationToken("DIFFERENT_KEY", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList2, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertTrue(!token1.equals(token2));
}
public void testNotEqualsDueToProxyGrantingTicket() {
List proxyList1 = new Vector();
proxyList1.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
List proxyList2 = new Vector();
proxyList2.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token2 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList2, "PGTIOU-SOME_OTHER_VALUE");
assertTrue(!token1.equals(token2));
}
public void testNotEqualsDueToProxyList() {
List proxyList1 = new Vector();
proxyList1.add("https://localhost/newPortal/j_spring_cas_security_check");
CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
List proxyList2 = new Vector();
proxyList2.add("https://localhost/SOME_OTHER_PORTAL/j_spring_cas_security_check");
CasAuthenticationToken token2 = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), proxyList2, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertTrue(!token1.equals(token2));
}
public void testSetAuthenticated() {
CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertTrue(token.isAuthenticated());
token.setAuthenticated(false);
assertTrue(!token.isAuthenticated());
}
public void testToString() {
CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
String result = token.toString();
assertTrue(result.lastIndexOf("Proxy List:") != -1);
assertTrue(result.lastIndexOf("Proxy-Granting Ticket IOU:") != -1);
assertTrue(result.lastIndexOf("Credentials (Service/Proxy Ticket):") != -1);
}
}
@@ -0,0 +1,102 @@
/* 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.springframework.security.providers.cas;
import junit.framework.TestCase;
import java.util.List;
import java.util.Vector;
/**
* Tests {@link TicketResponse}.
*
* @author Ben Alex
* @version $Id$
*/
public class TicketResponseTests extends TestCase {
//~ Constructors ===================================================================================================
public TicketResponseTests() {
super();
}
public TicketResponseTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(TicketResponseTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testConstructorAcceptsNullProxyGrantingTicketIOU() {
TicketResponse ticket = new TicketResponse("rod", new Vector(), null);
assertEquals("", ticket.getProxyGrantingTicketIou());
}
public void testConstructorAcceptsNullProxyList() {
TicketResponse ticket = new TicketResponse("rod", null,
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertEquals(new Vector(), ticket.getProxyList());
}
public void testConstructorRejectsNullUser() {
try {
new TicketResponse(null, new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGetters() {
// Build the proxy list returned in the ticket from CAS
List proxyList = new Vector();
proxyList.add("https://localhost/newPortal/j_spring_cas_security_check");
TicketResponse ticket = new TicketResponse("rod", proxyList,
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertEquals("rod", ticket.getUser());
assertEquals(proxyList, ticket.getProxyList());
assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt", ticket.getProxyGrantingTicketIou());
}
public void testNoArgConstructorDoesntExist() {
Class clazz = TicketResponse.class;
try {
clazz.getDeclaredConstructor((Class[]) null);
fail("Should have thrown NoSuchMethodException");
} catch (NoSuchMethodException expected) {
assertTrue(true);
}
}
public void testToString() {
TicketResponse ticket = new TicketResponse("rod", null,
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
String result = ticket.toString();
assertTrue(result.lastIndexOf("Proxy List:") != -1);
assertTrue(result.lastIndexOf("Proxy-Granting Ticket IOU:") != -1);
assertTrue(result.lastIndexOf("User:") != -1);
}
}
@@ -0,0 +1,105 @@
/* 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.springframework.security.providers.cas.cache;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Cache;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.providers.cas.CasAuthenticationToken;
import org.springframework.security.userdetails.User;
import java.util.List;
import java.util.Vector;
import org.junit.Test;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import static org.junit.Assert.*;
/**
* Tests {@link EhCacheBasedTicketCache}.
*
* @author Ben Alex
* @version $Id$
*/
public class EhCacheBasedTicketCacheTests {
static CacheManager cacheManager;
//~ Methods ========================================================================================================
@BeforeClass
public static void initCacheManaer() {
cacheManager = new CacheManager();
cacheManager.addCache(new Cache("castickets", 500, false, false, 30, 30));
}
@AfterClass
public static void shutdownCacheManager() {
cacheManager.removalAll();
cacheManager.shutdown();
}
private CasAuthenticationToken getToken() {
List proxyList = new Vector();
proxyList.add("https://localhost/newPortal/j_spring_cas_security_check");
User user = new User("rod", "password", true, true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
return new CasAuthenticationToken("key", user, "ST-0-ER94xMJmn6pha35CQRoZ",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, user,
proxyList, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
}
@Test
public void testCacheOperation() throws Exception {
EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
cache.setCache(cacheManager.getCache("castickets"));
cache.afterPropertiesSet();
// Check it gets stored in the cache
cache.putTicketInCache(getToken());
assertEquals(getToken(), cache.getByTicketId("ST-0-ER94xMJmn6pha35CQRoZ"));
// Check it gets removed from the cache
cache.removeTicketFromCache(getToken());
assertNull(cache.getByTicketId("ST-0-ER94xMJmn6pha35CQRoZ"));
// Check it doesn't return values for null or unknown service tickets
assertNull(cache.getByTicketId(null));
assertNull(cache.getByTicketId("UNKNOWN_SERVICE_TICKET"));
}
@Test
public void testStartupDetectsMissingCache() throws Exception {
EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
try {
cache.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
Ehcache myCache = cacheManager.getCache("castickets");
cache.setCache(myCache);
assertEquals(myCache, cache.getCache());
}
}
@@ -0,0 +1,62 @@
/* 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.springframework.security.providers.cas.cache;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.providers.cas.CasAuthenticationToken;
import org.springframework.security.providers.cas.StatelessTicketCache;
import org.springframework.security.userdetails.User;
import junit.framework.TestCase;
/**
* Test cases for the @link {@link NullStatelessTicketCache}
*
* @author Scott Battaglia
* @version $Id$
*
*/
public class NullStatelessTicketCacheTests extends TestCase {
private StatelessTicketCache cache = new NullStatelessTicketCache();
public void testGetter() {
assertNull(cache.getByTicketId(null));
assertNull(cache.getByTicketId("test"));
}
public void testInsertAndGet() {
final CasAuthenticationToken token = getToken();
cache.putTicketInCache(token);
assertNull(cache.getByTicketId((String) token.getCredentials()));
}
private CasAuthenticationToken getToken() {
List<String> proxyList = new ArrayList<String>();
proxyList.add("https://localhost/newPortal/j_spring_cas_security_check");
User user = new User("rod", "password", true, true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
return new CasAuthenticationToken("key", user, "ST-0-ER94xMJmn6pha35CQRoZ",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, user,
proxyList, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
}
}
@@ -0,0 +1,66 @@
/* 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.springframework.security.providers.cas.proxy;
import junit.framework.TestCase;
import java.util.Vector;
/**
* Tests {@link AcceptAnyCasProxy}.
*
* @author Ben Alex
* @version $Id$
*/
public class AcceptAnyCasProxyTests extends TestCase {
//~ Constructors ===================================================================================================
public AcceptAnyCasProxyTests() {
super();
}
public AcceptAnyCasProxyTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(AcceptAnyCasProxyTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testDoesNotAcceptNull() {
AcceptAnyCasProxy proxyDecider = new AcceptAnyCasProxy();
try {
proxyDecider.confirmProxyListTrusted(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("proxyList cannot be null", expected.getMessage());
}
}
public void testNormalOperation() {
AcceptAnyCasProxy proxyDecider = new AcceptAnyCasProxy();
proxyDecider.confirmProxyListTrusted(new Vector());
assertTrue(true); // as no Exception thrown
}
}
@@ -0,0 +1,134 @@
/* 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.springframework.security.providers.cas.proxy;
import junit.framework.TestCase;
import org.springframework.security.providers.cas.ProxyUntrustedException;
import java.util.List;
import java.util.Vector;
/**
* Tests {@link NamedCasProxyDecider}.
*/
public class NamedCasProxyDeciderTests extends TestCase {
//~ Constructors ===================================================================================================
public NamedCasProxyDeciderTests() {
super();
}
public NamedCasProxyDeciderTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(NamedCasProxyDeciderTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testAcceptsIfNearestProxyIsAuthorized()
throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
// Build the ticket returned from CAS
List proxyList = new Vector();
proxyList.add("https://localhost/newPortal/j_spring_cas_security_check");
// Build the list of valid nearest proxies
List validProxies = new Vector();
validProxies.add("https://localhost/portal/j_spring_cas_security_check");
validProxies.add("https://localhost/newPortal/j_spring_cas_security_check");
proxyDecider.setValidProxies(validProxies);
proxyDecider.afterPropertiesSet();
proxyDecider.confirmProxyListTrusted(proxyList);
assertTrue(true);
}
public void testAcceptsIfNoProxiesInTicket() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
List proxyList = new Vector(); // no proxies in list
proxyDecider.confirmProxyListTrusted(proxyList);
assertTrue(true);
}
public void testDetectsMissingValidProxiesList() throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
try {
proxyDecider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("A validProxies list must be set", expected.getMessage());
}
}
public void testDoesNotAcceptNull() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
try {
proxyDecider.confirmProxyListTrusted(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("proxyList cannot be null", expected.getMessage());
}
}
public void testGettersSetters() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
// Build the list of valid nearest proxies
List validProxies = new Vector();
validProxies.add("https://localhost/portal/j_spring_cas_security_check");
validProxies.add("https://localhost/newPortal/j_spring_cas_security_check");
proxyDecider.setValidProxies(validProxies);
assertEquals(validProxies, proxyDecider.getValidProxies());
}
public void testRejectsIfNearestProxyIsNotAuthorized()
throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
// Build the ticket returned from CAS
List proxyList = new Vector();
proxyList.add("https://localhost/untrustedWebApp/j_spring_cas_security_check");
// Build the list of valid nearest proxies
List validProxies = new Vector();
validProxies.add("https://localhost/portal/j_spring_cas_security_check");
validProxies.add("https://localhost/newPortal/j_spring_cas_security_check");
proxyDecider.setValidProxies(validProxies);
proxyDecider.afterPropertiesSet();
try {
proxyDecider.confirmProxyListTrusted(proxyList);
fail("Should have thrown ProxyUntrustedException");
} catch (ProxyUntrustedException expected) {
assertTrue(true);
}
}
}
@@ -0,0 +1,84 @@
/* 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.springframework.security.providers.cas.proxy;
import junit.framework.TestCase;
import org.springframework.security.providers.cas.ProxyUntrustedException;
import java.util.List;
import java.util.Vector;
/**
* Tests {@link RejectProxyTickets}.
*
* @author Ben Alex
* @version $Id$
*/
public class RejectProxyTicketsTests extends TestCase {
//~ Constructors ===================================================================================================
public RejectProxyTicketsTests() {
super();
}
public RejectProxyTicketsTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(RejectProxyTicketsTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testAcceptsIfNoProxiesInTicket() {
RejectProxyTickets proxyDecider = new RejectProxyTickets();
List proxyList = new Vector(); // no proxies in list
proxyDecider.confirmProxyListTrusted(proxyList);
assertTrue(true);
}
public void testDoesNotAcceptNull() {
RejectProxyTickets proxyDecider = new RejectProxyTickets();
try {
proxyDecider.confirmProxyListTrusted(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("proxyList cannot be null", expected.getMessage());
}
}
public void testRejectsIfAnyProxyInList() {
RejectProxyTickets proxyDecider = new RejectProxyTickets();
List proxyList = new Vector();
proxyList.add("https://localhost/webApp/j_spring_cas_security_check");
try {
proxyDecider.confirmProxyListTrusted(proxyList);
fail("Should have thrown ProxyUntrustedException");
} catch (ProxyUntrustedException expected) {
assertTrue(true);
}
}
}
@@ -0,0 +1,147 @@
/* 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.springframework.security.providers.cas.ticketvalidator;
import junit.framework.TestCase;
import org.springframework.security.AuthenticationException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.providers.cas.TicketResponse;
import org.springframework.security.ui.cas.ServiceProperties;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ClassPathResource;
import java.util.Vector;
/**
* Tests {@link AbstractTicketValidator}.
*
* @author Ben Alex
* @version $Id$
*/
public class AbstractTicketValidatorTests extends TestCase {
//~ Constructors ===================================================================================================
public AbstractTicketValidatorTests() {
}
public AbstractTicketValidatorTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public void testDetectsMissingCasValidate() throws Exception {
AbstractTicketValidator tv = new MockAbstractTicketValidator();
tv.setServiceProperties(new ServiceProperties());
try {
tv.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("A casValidate URL must be set", expected.getMessage());
}
}
public void testDetectsMissingServiceProperties() throws Exception {
AbstractTicketValidator tv = new MockAbstractTicketValidator();
tv.setCasValidate("https://company.com/cas/proxyvalidate");
try {
tv.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("serviceProperties must be specified", expected.getMessage());
}
}
public void testGetters() throws Exception {
AbstractTicketValidator tv = new MockAbstractTicketValidator();
tv.setCasValidate("https://company.com/cas/proxyvalidate");
assertEquals("https://company.com/cas/proxyvalidate", tv.getCasValidate());
tv.setServiceProperties(new ServiceProperties());
assertTrue(tv.getServiceProperties() != null);
tv.afterPropertiesSet();
tv.setTrustStore("/some/file/cacerts");
assertEquals("/some/file/cacerts", tv.getTrustStore());
}
public void testTrustStoreSystemPropertySetDuringAfterPropertiesSet() throws Exception {
AbstractTicketValidator tv = new MockAbstractTicketValidator();
tv.setCasValidate("https://company.com/cas/proxyvalidate");
tv.setServiceProperties(new ServiceProperties());
// We need an existing file to use as the truststore property
Resource r = new ClassPathResource("log4j.properties");
String filename = r.getFile().getAbsolutePath();
tv.setTrustStore(filename);
assertEquals(filename, tv.getTrustStore());
String before = System.getProperty("javax.net.ssl.trustStore");
tv.afterPropertiesSet();
assertEquals(filename, System.getProperty("javax.net.ssl.trustStore"));
if (before == null) {
System.setProperty("javax.net.ssl.trustStore", "");
} else {
System.setProperty("javax.net.ssl.trustStore", before);
}
}
public void testMissingTrustStoreFileCausesException() throws Exception {
AbstractTicketValidator tv = new MockAbstractTicketValidator();
tv.setServiceProperties(new ServiceProperties());
tv.setCasValidate("https://company.com/cas/proxyvalidate");
tv.setTrustStore("/non/existent/file");
try {
tv.afterPropertiesSet();
fail("Expected exception with non-existent truststore");
} catch (IllegalArgumentException expected) {
}
}
//~ Inner Classes ==================================================================================================
private class MockAbstractTicketValidator extends AbstractTicketValidator {
private boolean returnTicket;
public MockAbstractTicketValidator(boolean returnTicket) {
this.returnTicket = returnTicket;
}
private MockAbstractTicketValidator() {
}
public TicketResponse confirmTicketValid(String serviceTicket)
throws AuthenticationException {
if (returnTicket) {
return new TicketResponse("user", new Vector(),
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
}
throw new BadCredentialsException("As requested by mock");
}
}
}
@@ -0,0 +1,136 @@
/* 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.springframework.security.providers.cas.ticketvalidator;
import edu.yale.its.tp.cas.client.ProxyTicketValidator;
import junit.framework.TestCase;
import org.springframework.security.AuthenticationServiceException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.providers.cas.TicketResponse;
import org.springframework.security.ui.cas.ServiceProperties;
import java.util.Vector;
/**
* Tests {@link CasProxyTicketValidator}.
*
* @author Ben Alex
* @version $Id$
*/
public class CasProxyTicketValidatorTests extends TestCase {
//~ Constructors ===================================================================================================
public CasProxyTicketValidatorTests() {
super();
}
public CasProxyTicketValidatorTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(CasProxyTicketValidatorTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testGetters() {
CasProxyTicketValidator tv = new CasProxyTicketValidator();
tv.setProxyCallbackUrl("http://my.com/webapp/casProxy/someValidator");
assertEquals("http://my.com/webapp/casProxy/someValidator", tv.getProxyCallbackUrl());
}
public void testNormalOperation() {
ServiceProperties sp = new ServiceProperties();
sp.setSendRenew(true);
sp.setService("https://my.com/webapp//j_spring_cas_security_check");
CasProxyTicketValidator tv = new MockCasProxyTicketValidator(true, false);
tv.setCasValidate("https://company.com/cas/proxyvalidate");
tv.setServiceProperties(sp);
tv.setProxyCallbackUrl("http://my.com/webapp/casProxy/someValidator");
TicketResponse response = tv.confirmTicketValid("ST-0-ER94xMJmn6pha35CQRoZ");
assertEquals("user", response.getUser());
}
public void testProxyTicketValidatorInternalExceptionsGracefullyHandled() {
CasProxyTicketValidator tv = new MockCasProxyTicketValidator(false, true);
tv.setCasValidate("https://company.com/cas/proxyvalidate");
tv.setServiceProperties(new ServiceProperties());
tv.setProxyCallbackUrl("http://my.com/webapp/casProxy/someValidator");
try {
tv.confirmTicketValid("ST-0-ER94xMJmn6pha35CQRoZ");
fail("Should have thrown AuthenticationServiceException");
} catch (AuthenticationServiceException expected) {
assertTrue(true);
}
}
public void testValidationFailsOkAndOperationWithoutAProxyCallbackUrl() {
CasProxyTicketValidator tv = new MockCasProxyTicketValidator(false, false);
tv.setCasValidate("https://company.com/cas/proxyvalidate");
tv.setServiceProperties(new ServiceProperties());
try {
tv.confirmTicketValid("ST-0-ER94xMJmn6pha35CQRoZ");
fail("Should have thrown BadCredentialsExpected");
} catch (BadCredentialsException expected) {
assertTrue(true);
}
}
//~ Inner Classes ==================================================================================================
private class MockCasProxyTicketValidator extends CasProxyTicketValidator {
private boolean returnTicket;
private boolean throwAuthenticationServiceException;
public MockCasProxyTicketValidator(boolean returnTicket, boolean throwAuthenticationServiceException) {
this.returnTicket = returnTicket;
this.throwAuthenticationServiceException = throwAuthenticationServiceException;
}
private MockCasProxyTicketValidator() {
super();
}
protected TicketResponse validateNow(ProxyTicketValidator pv)
throws AuthenticationServiceException, BadCredentialsException {
if (returnTicket) {
return new TicketResponse("user", new Vector(),
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
}
if (throwAuthenticationServiceException) {
throw new AuthenticationServiceException("As requested by mock");
}
throw new BadCredentialsException("As requested by mock");
}
}
}
+41
View File
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0-SNAPSHOT</version>
</parent>
<artifactId>spring-security-cas</artifactId>
<name>Spring Security - CAS Support</name>
<packaging>pom</packaging>
<modules>
<module>cas-client</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-dao</artifactId>
</dependency>
<dependency>
<groupId>cas</groupId>
<artifactId>casclient</artifactId>
<version>2.0.11</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.3.0</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>