Initial CAS support.
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.providers.AuthenticationProvider;
|
||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import net.sf.acegisecurity.ui.cas.CasProcessingFilter;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
|
||||
/**
|
||||
* An {@link AuthenticationProvider} implementation that integrates with Yale
|
||||
* 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}.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasAuthenticationProvider implements AuthenticationProvider,
|
||||
InitializingBean {
|
||||
//~ Static fields/initializers =============================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private CasAuthoritiesPopulator casAuthoritiesPopulator;
|
||||
private CasProxyDecider casProxyDecider;
|
||||
private StatelessTicketCache statelessTicketCache;
|
||||
private String key;
|
||||
private TicketValidator ticketValidator;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setCasAuthoritiesPopulator(
|
||||
CasAuthoritiesPopulator casAuthoritiesPopulator) {
|
||||
this.casAuthoritiesPopulator = casAuthoritiesPopulator;
|
||||
}
|
||||
|
||||
public CasAuthoritiesPopulator getCasAuthoritiesPopulator() {
|
||||
return casAuthoritiesPopulator;
|
||||
}
|
||||
|
||||
public void setCasProxyDecider(CasProxyDecider casProxyDecider) {
|
||||
this.casProxyDecider = casProxyDecider;
|
||||
}
|
||||
|
||||
public CasProxyDecider getCasProxyDecider() {
|
||||
return casProxyDecider;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setStatelessTicketCache(
|
||||
StatelessTicketCache statelessTicketCache) {
|
||||
this.statelessTicketCache = statelessTicketCache;
|
||||
}
|
||||
|
||||
public StatelessTicketCache getStatelessTicketCache() {
|
||||
return statelessTicketCache;
|
||||
}
|
||||
|
||||
public void setTicketValidator(TicketValidator ticketValidator) {
|
||||
this.ticketValidator = ticketValidator;
|
||||
}
|
||||
|
||||
public TicketValidator getTicketValidator() {
|
||||
return ticketValidator;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.casAuthoritiesPopulator == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"A casAuthoritiesPopulator must be set");
|
||||
}
|
||||
|
||||
if (this.ticketValidator == null) {
|
||||
throw new IllegalArgumentException("A ticketValidator must be set");
|
||||
}
|
||||
|
||||
if (this.casProxyDecider == null) {
|
||||
throw new IllegalArgumentException("A casProxyDecider must be set");
|
||||
}
|
||||
|
||||
if (this.statelessTicketCache == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"A statelessTicketCache must be set");
|
||||
}
|
||||
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated");
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
"The presented CasAuthenticationToken does not contain the expected key");
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure credentials are presented
|
||||
if (authentication.getCredentials() == null || "".equals(authentication.getCredentials())) {
|
||||
throw new BadCredentialsException(
|
||||
"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);
|
||||
}
|
||||
|
||||
if (stateless) {
|
||||
// Add to cache
|
||||
statelessTicketCache.putTicketInCache(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean supports(Class authentication) {
|
||||
if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(
|
||||
authentication)) {
|
||||
return true;
|
||||
} else if (CasAuthenticationToken.class.isAssignableFrom(authentication)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
// Build list of granted authorities
|
||||
GrantedAuthority[] ga = this.casAuthoritiesPopulator.getAuthorities(response
|
||||
.getUser());
|
||||
|
||||
// Construct CasAuthenticationToken
|
||||
return new CasAuthenticationToken(this.key, response.getUser(),
|
||||
authentication.getCredentials(), ga, response.getProxyList(),
|
||||
response.getProxyGrantingTicketIou());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas;
|
||||
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.providers.AbstractAuthenticationToken;
|
||||
|
||||
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 List proxyList;
|
||||
private Object credentials;
|
||||
private Object principal;
|
||||
private String proxyGrantingTicketIou;
|
||||
private GrantedAuthority[] authorities;
|
||||
private int keyHash;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param key to identify if this object made by a given {@link
|
||||
* CasAuthenticationProvider}
|
||||
* @param principal the username from CAS (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 {@link
|
||||
* CasAuthoritiesPopulator}) (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>)
|
||||
*
|
||||
* @throws IllegalArgumentException if a <code>null</code> was passed
|
||||
*/
|
||||
public CasAuthenticationToken(String key, Object principal,
|
||||
Object credentials, GrantedAuthority[] authorities, List proxyList,
|
||||
String proxyGrantingTicketIou) {
|
||||
if ((key == null) || ("".equals(key)) || (principal == null)
|
||||
|| "".equals(principal) || (credentials == null)
|
||||
|| "".equals(credentials) || (authorities == null)
|
||||
|| (proxyList == null) || (proxyGrantingTicketIou == null)
|
||||
|| ("".equals(proxyGrantingTicketIou))) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot pass null or empty values to constructor");
|
||||
}
|
||||
|
||||
for (int i = 0; i < authorities.length; i++) {
|
||||
if (authorities[i] == null) {
|
||||
throw new IllegalArgumentException("Granted authority element "
|
||||
+ i
|
||||
+ " is null - GrantedAuthority[] cannot contain any null elements");
|
||||
}
|
||||
}
|
||||
|
||||
this.keyHash = key.hashCode();
|
||||
this.principal = principal;
|
||||
this.credentials = credentials;
|
||||
this.authorities = authorities;
|
||||
this.proxyList = proxyList;
|
||||
this.proxyGrantingTicketIou = proxyGrantingTicketIou;
|
||||
}
|
||||
|
||||
protected CasAuthenticationToken() {
|
||||
throw new IllegalArgumentException("Cannot use default constructor");
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
/**
|
||||
* Ignored (always <code>true</code>).
|
||||
*
|
||||
* @param isAuthenticated ignored
|
||||
*/
|
||||
public void setAuthenticated(boolean isAuthenticated) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns <code>true</code>.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public boolean isAuthenticated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public GrantedAuthority[] getAuthorities() {
|
||||
return this.authorities;
|
||||
}
|
||||
|
||||
public Object getCredentials() {
|
||||
return this.credentials;
|
||||
}
|
||||
|
||||
public int getKeyHash() {
|
||||
return this.keyHash;
|
||||
}
|
||||
|
||||
public Object getPrincipal() {
|
||||
return this.principal;
|
||||
}
|
||||
|
||||
public String getProxyGrantingTicketIou() {
|
||||
return proxyGrantingTicketIou;
|
||||
}
|
||||
|
||||
public List getProxyList() {
|
||||
return proxyList;
|
||||
}
|
||||
|
||||
public boolean equals(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;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
System.out.println("THey're not equal");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(super.toString());
|
||||
sb.append("; Credentials (Service/Proxy Ticket): " + this.credentials);
|
||||
sb.append("; Proxy-Granting Ticket IOU: " + this.proxyGrantingTicketIou);
|
||||
sb.append("; Proxy List: " + this.proxyList.toString());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas;
|
||||
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
|
||||
|
||||
/**
|
||||
* Populates the <code>GrantedAuthority[]</code> objects for a CAS
|
||||
* authenticated user.
|
||||
*
|
||||
* <P>
|
||||
* CAS does not provide the authorities (roles) granted to a user. It merely
|
||||
* authenticates their identity. As the Acegi Security System for Spring needs
|
||||
* to know the authorities granted to a user in order to construct a valid
|
||||
* <code>Authentication</code> object, implementations of this interface will
|
||||
* provide this information.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* Implementations should not perform any caching. They will only be called
|
||||
* when a refresh is required.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface CasAuthoritiesPopulator {
|
||||
//~ Methods ================================================================
|
||||
|
||||
/**
|
||||
* Obtains the granted authorities for the specified user.
|
||||
*
|
||||
* <P>
|
||||
* May throw any <code>AuthenticationException</code> or return
|
||||
* <code>null</code> if the authorities are unavailable.
|
||||
* </p>
|
||||
*
|
||||
* @param casUserId as obtained from the CAS validation service
|
||||
*
|
||||
* @return the granted authorities for the indicated user
|
||||
*/
|
||||
public GrantedAuthority[] getAuthorities(String casUserId)
|
||||
throws AuthenticationException;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/* 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 net.sf.acegisecurity.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>
|
||||
*/
|
||||
public void confirmProxyListTrusted(List proxyList)
|
||||
throws ProxyUntrustedException;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas;
|
||||
|
||||
import net.sf.acegisecurity.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 net.sf.acegisecurity.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 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 Acegi Security System 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
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
public void removeTicketFromCache(String serviceTicket);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/* 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 net.sf.acegisecurity.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;
|
||||
}
|
||||
|
||||
protected TicketResponse() {
|
||||
throw new IllegalArgumentException("Cannot use default constructor");
|
||||
}
|
||||
|
||||
//~ 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 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 net.sf.acegisecurity.providers.cas;
|
||||
|
||||
import net.sf.acegisecurity.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>
|
||||
*
|
||||
* @return details of the CAS service ticket
|
||||
*/
|
||||
public TicketResponse confirmTicketValid(String serviceTicket)
|
||||
throws AuthenticationException;
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.cache;
|
||||
|
||||
import net.sf.acegisecurity.providers.cas.CasAuthenticationToken;
|
||||
import net.sf.acegisecurity.providers.cas.StatelessTicketCache;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheException;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Element;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
|
||||
/**
|
||||
* Caches tickets using <A HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EhCacheBasedTicketCache implements StatelessTicketCache,
|
||||
InitializingBean {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private Cache cache;
|
||||
private CacheManager manager;
|
||||
private int minutesToIdle = 20;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public CasAuthenticationToken getByTicketId(String serviceTicket) {
|
||||
Element element = null;
|
||||
|
||||
try {
|
||||
element = cache.get(serviceTicket);
|
||||
} catch (CacheException cacheException) {
|
||||
throw new DataRetrievalFailureException("Cache failure: "
|
||||
+ cacheException.getMessage());
|
||||
}
|
||||
|
||||
if (element == null) {
|
||||
System.out.println("not found");
|
||||
|
||||
return null;
|
||||
} else {
|
||||
System.out.println("found");
|
||||
|
||||
return (CasAuthenticationToken) element.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMinutesToIdle(int minutesToIdle) {
|
||||
this.minutesToIdle = minutesToIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies how many minutes an entry will remain in the cache from when
|
||||
* it was last accessed. This is effectively the session duration.
|
||||
*
|
||||
* <P>
|
||||
* Defaults to 20 minutes.
|
||||
* </p>
|
||||
*
|
||||
* @return Returns the minutes an element remains in the cache
|
||||
*/
|
||||
public int getMinutesToIdle() {
|
||||
return minutesToIdle;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
manager = CacheManager.create();
|
||||
|
||||
// Cache name, max memory, overflowToDisk, eternal, timeToLive, timeToIdle
|
||||
cache = new Cache("ehCacheBasedTicketCache", Integer.MAX_VALUE, false,
|
||||
false, minutesToIdle * 60, minutesToIdle * 60);
|
||||
manager.addCache(cache);
|
||||
}
|
||||
|
||||
public void putTicketInCache(CasAuthenticationToken token) {
|
||||
Element element = new Element(token.getCredentials().toString(), token);
|
||||
System.out.println("Adding " + element.getKey());
|
||||
cache.put(element);
|
||||
}
|
||||
|
||||
public void removeTicketFromCache(CasAuthenticationToken token) {
|
||||
this.removeTicketFromCache(token.getCredentials().toString());
|
||||
}
|
||||
|
||||
public void removeTicketFromCache(String serviceTicket) {
|
||||
cache.remove(serviceTicket);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
An authentication provider that can process Yale Central Authentication Service (CAS)
|
||||
service tickets and proxy tickets.
|
||||
</body>
|
||||
</html>
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.populator;
|
||||
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.providers.cas.CasAuthoritiesPopulator;
|
||||
import net.sf.acegisecurity.providers.dao.AuthenticationDao;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
|
||||
/**
|
||||
* Populates the CAS authorities via an {@link AuthenticationDao}.
|
||||
*
|
||||
* <P>
|
||||
* The additional information (username, password, enabled status etc) an
|
||||
* <code>AuthenticationDao</code> implementation provides about a
|
||||
* <code>User</code> is ignored. Only the <code>GrantedAuthority</code>s are
|
||||
* relevant to this class.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class DaoCasAuthoritiesPopulator implements CasAuthoritiesPopulator,
|
||||
InitializingBean {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private AuthenticationDao authenticationDao;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
|
||||
this.authenticationDao = authenticationDao;
|
||||
}
|
||||
|
||||
public AuthenticationDao getAuthenticationDao() {
|
||||
return authenticationDao;
|
||||
}
|
||||
|
||||
public GrantedAuthority[] getAuthorities(String casUserId)
|
||||
throws AuthenticationException {
|
||||
return this.authenticationDao.loadUserByUsername(casUserId)
|
||||
.getAuthorities();
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.authenticationDao == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"An authenticationDao must be set");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Implementations that populate GrantedAuthority[]s of CAS authentications.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,55 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.proxy;
|
||||
|
||||
import net.sf.acegisecurity.providers.cas.CasProxyDecider;
|
||||
import net.sf.acegisecurity.providers.cas.ProxyUntrustedException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
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 {
|
||||
if (proxyList == null) {
|
||||
throw new IllegalArgumentException("proxyList cannot be null");
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Always accepting proxy list: " + proxyList.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.proxy;
|
||||
|
||||
import net.sf.acegisecurity.providers.cas.CasProxyDecider;
|
||||
import net.sf.acegisecurity.providers.cas.ProxyUntrustedException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
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>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
|
||||
//~ Static fields/initializers =============================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(NamedCasProxyDecider.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private List validProxies;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setValidProxies(List validProxies) {
|
||||
this.validProxies = validProxies;
|
||||
}
|
||||
|
||||
public List getValidProxies() {
|
||||
return validProxies;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.validProxies == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"A validProxies list must be set");
|
||||
}
|
||||
}
|
||||
|
||||
public void confirmProxyListTrusted(List proxyList)
|
||||
throws ProxyUntrustedException {
|
||||
if (proxyList == null) {
|
||||
throw new IllegalArgumentException("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("Nearest proxy '"
|
||||
+ proxyList.get(0) + "' is untrusted");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.proxy;
|
||||
|
||||
import net.sf.acegisecurity.providers.cas.CasProxyDecider;
|
||||
import net.sf.acegisecurity.providers.cas.ProxyUntrustedException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
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>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class RejectProxyTickets implements CasProxyDecider {
|
||||
//~ Static fields/initializers =============================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(RejectProxyTickets.class);
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void confirmProxyListTrusted(List proxyList)
|
||||
throws ProxyUntrustedException {
|
||||
if (proxyList == null) {
|
||||
throw new IllegalArgumentException("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("Proxy tickets are rejected");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
Implementations that decide whether proxy lists of
|
||||
CAS authentications are trusted.
|
||||
</body>
|
||||
</html>
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.ticketvalidator;
|
||||
|
||||
import net.sf.acegisecurity.providers.cas.TicketValidator;
|
||||
import net.sf.acegisecurity.ui.cas.ServiceProperties;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience abstract base for <code>TicketValidator</code>s.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractTicketValidator implements TicketValidator,
|
||||
InitializingBean {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private ServiceProperties serviceProperties;
|
||||
private String casValidate;
|
||||
private String trustStore;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setCasValidate(String casValidate) {
|
||||
this.casValidate = casValidate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 void setServiceProperties(ServiceProperties serviceProperties) {
|
||||
this.serviceProperties = serviceProperties;
|
||||
}
|
||||
|
||||
public ServiceProperties getServiceProperties() {
|
||||
return serviceProperties;
|
||||
}
|
||||
|
||||
public void setTrustStore(String trustStore) {
|
||||
this.trustStore = trustStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 afterPropertiesSet() throws Exception {
|
||||
if ((this.casValidate == null) || "".equals(casValidate)) {
|
||||
throw new IllegalArgumentException("A casValidate URL must be set");
|
||||
}
|
||||
|
||||
if (serviceProperties == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"serviceProperties must be specified");
|
||||
}
|
||||
|
||||
if ((trustStore != null) && (!"".equals(trustStore))) {
|
||||
System.setProperty("javax.net.ssl.trustStore", trustStore);
|
||||
}
|
||||
}
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.ticketvalidator;
|
||||
|
||||
import edu.yale.its.tp.cas.client.ProxyTicketValidator;
|
||||
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.AuthenticationServiceException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.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 void setProxyCallbackUrl(String proxyCallbackUrl) {
|
||||
this.proxyCallbackUrl = proxyCallbackUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional callback URL to obtain a proxy-granting ticket from CAS.
|
||||
*
|
||||
* <P>
|
||||
* This callback URL belongs to the Acegi Security System for Spring
|
||||
* 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 Acegi Securty System
|
||||
* for Spring 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 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,111 @@
|
||||
/* 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 net.sf.acegisecurity.ui.cas;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import net.sf.acegisecurity.ui.AbstractProcessingFilter;
|
||||
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Processes a CAS service ticket.
|
||||
*
|
||||
* <p>
|
||||
* A service ticket consists of an opaque ticket string. It arrives at this
|
||||
* filter by the user's browser successfully authenticating using CAS, and
|
||||
* then receiving a HTTP redirect to a <code>service</code>. The opal ticket
|
||||
* string is presented in the <code>ticket</code> request parameter. This
|
||||
* filter monitors the <code>service</code> URL so it can receive the service
|
||||
* ticket and process it. The CAS server knows which <code>service</code> URL
|
||||
* to use via the {@link ServiceProperties#getService()} method.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* Processing the service ticket involves creating a
|
||||
* <code>UsernamePasswordAuthenticationToken</code> which uses {@link
|
||||
* #CAS_STATEFUL_IDENTIFIER} for the <code>principal</code> and the opaque
|
||||
* ticket string as the <code>credentials</code>.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* The configured <code>AuthenticationManager</code> is expected to provide a
|
||||
* provider that can recognise
|
||||
* <code>UsernamePasswordAuthenticationToken</code>s containing this special
|
||||
* <code>principal</code> name, and process them accordingly by validation
|
||||
* with the CAS server.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* <B>Do not use this class directly.</B> Instead configure
|
||||
* <code>web.xml</code> to use the {@link
|
||||
* net.sf.acegisecurity.util.FilterToBeanProxy}.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasProcessingFilter extends AbstractProcessingFilter {
|
||||
//~ Static fields/initializers =============================================
|
||||
|
||||
/**
|
||||
* Used to identify a CAS request for a stateful user agent, such as a web
|
||||
* browser.
|
||||
*/
|
||||
public static final String CAS_STATEFUL_IDENTIFIER = "_cas_stateful_";
|
||||
|
||||
/**
|
||||
* Used to identify a CAS request for a stateless user agent, such as a
|
||||
* remoting protocol client (eg Hessian, Burlap, SOAP etc). Results in a
|
||||
* more aggressive caching strategy being used, as the absence of a
|
||||
* <code>HttpSession</code> will result in a new authentication attempt on
|
||||
* every request.
|
||||
*/
|
||||
public static final String CAS_STATELESS_IDENTIFIER = "_cas_stateless_";
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
/**
|
||||
* This filter by default responds to
|
||||
* <code>/j_acegi_cas_security_check</code>.
|
||||
*
|
||||
* @return the default
|
||||
*/
|
||||
public String getDefaultFilterProcessesUrl() {
|
||||
return "/j_acegi_cas_security_check";
|
||||
}
|
||||
|
||||
public Authentication attemptAuthentication(HttpServletRequest request)
|
||||
throws AuthenticationException {
|
||||
String username = CAS_STATEFUL_IDENTIFIER;
|
||||
String password = request.getParameter("ticket");
|
||||
|
||||
if (password == null) {
|
||||
password = "";
|
||||
}
|
||||
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
|
||||
password);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
}
|
||||
|
||||
public void init(FilterConfig filterConfig) throws ServletException {}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/* 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 net.sf.acegisecurity.ui.cas;
|
||||
|
||||
import net.sf.acegisecurity.intercept.web.AuthenticationEntryPoint;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Used by the <code>SecurityEnforcementFilter</code> to commence
|
||||
* authentication via the Yale Central Authentication Service (CAS).
|
||||
*
|
||||
* <P>
|
||||
* The user's browser will be redirected to the Yale CAS enterprise-wide login
|
||||
* page. This page is specified by the <code>loginUrl</code> property. Once
|
||||
* login is complete, the CAS login page will redirect to the page indicated
|
||||
* by the <code>service</code> property. The <code>service</code> is a HTTP
|
||||
* URL belonging to the current application. The <code>service</code> URL is
|
||||
* monitored by the {@link CasProcessingFilter}, which will validate the CAS
|
||||
* login was successful.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasProcessingFilterEntryPoint implements AuthenticationEntryPoint,
|
||||
InitializingBean {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private ServiceProperties serviceProperties;
|
||||
private String loginUrl;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setLoginUrl(String loginUrl) {
|
||||
this.loginUrl = loginUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* The enterprise-wide CAS login URL. Usually something like
|
||||
* <code>https://www.mycompany.com/cas/login</code>.
|
||||
*
|
||||
* @return the enterprise-wide CAS login URL
|
||||
*/
|
||||
public String getLoginUrl() {
|
||||
return loginUrl;
|
||||
}
|
||||
|
||||
public void setServiceProperties(ServiceProperties serviceProperties) {
|
||||
this.serviceProperties = serviceProperties;
|
||||
}
|
||||
|
||||
public ServiceProperties getServiceProperties() {
|
||||
return serviceProperties;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if ((loginUrl == null) || "".equals(loginUrl)) {
|
||||
throw new IllegalArgumentException("loginUrl must be specified");
|
||||
}
|
||||
|
||||
if (serviceProperties == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"serviceProperties must be specified");
|
||||
}
|
||||
}
|
||||
|
||||
public void commence(ServletRequest request, ServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
String url;
|
||||
|
||||
if (serviceProperties.isSendRenew()) {
|
||||
url = loginUrl + "?renew=true" + "&service="
|
||||
+ serviceProperties.getService();
|
||||
} else {
|
||||
url = loginUrl + "?service=" + serviceProperties.getService();
|
||||
}
|
||||
|
||||
((HttpServletResponse) response).sendRedirect(url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/* 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 net.sf.acegisecurity.ui.cas;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
|
||||
/**
|
||||
* Stores properties related to this CAS service.
|
||||
*
|
||||
* <P>
|
||||
* Each web application capable of processing CAS tickets is known as a
|
||||
* service. This class stores the properties that are relevant to the local
|
||||
* CAS service, being the application that is being secured by the Acegi
|
||||
* Security System for Spring.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ServiceProperties implements InitializingBean {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private String service;
|
||||
|
||||
private boolean sendRenew = false;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setSendRenew(boolean sendRenew) {
|
||||
this.sendRenew = sendRenew;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the <code>renew</code> parameter should be sent to the
|
||||
* CAS login URL and CAS validation URL.
|
||||
* <P> If <code>true</code>, it will
|
||||
* force CAS to authenticate the user again (even if the user has
|
||||
* previously authenticated). During ticket validation it will require the
|
||||
* ticket was generated as a consequence of an explicit login. High
|
||||
* security applications would probably set this to <code>true</code>.
|
||||
* Defaults to <code>false</code>, providing automated single sign on.
|
||||
*
|
||||
* @return whether to send the <code>renew</code> parameter to CAS
|
||||
*/
|
||||
public boolean isSendRenew() {
|
||||
return sendRenew;
|
||||
}
|
||||
|
||||
public void setService(String service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the service the user is authenticating to.
|
||||
*
|
||||
* <B>This service is the callback URL
|
||||
* belonging to the local Acegi Security System for Spring secured
|
||||
* application. For example,
|
||||
* <code>https://www.mycompany.com/application/j_acegi_cas_security_check</code>
|
||||
*
|
||||
* @return the URL of the service the user is authenticating to
|
||||
*/
|
||||
public String getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if ((service == null) || "".equals(service)) {
|
||||
throw new IllegalArgumentException("service must be specified");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
Authenticates standard web browser users via
|
||||
Yale Central Authentication Service (CAS).
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
package net.sf.acegisecurity.providers.dao;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
|
||||
|
||||
@@ -24,7 +26,7 @@ import net.sf.acegisecurity.GrantedAuthority;
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class User {
|
||||
public class User implements Serializable {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private String password;
|
||||
@@ -53,9 +55,10 @@ public class User {
|
||||
*/
|
||||
public User(String username, String password, boolean enabled,
|
||||
GrantedAuthority[] authorities) throws IllegalArgumentException {
|
||||
if ((username == null) || (password == null) || (authorities == null)) {
|
||||
if (((username == null) || "".equals(username)) || (password == null)
|
||||
|| "".equals(password) || (authorities == null)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot pass null values to constructor");
|
||||
"Cannot pass null or empty values to constructor");
|
||||
}
|
||||
|
||||
for (int i = 0; i < authorities.length; i++) {
|
||||
|
||||
@@ -47,7 +47,7 @@ import javax.servlet.http.HttpSession;
|
||||
public class MockHttpServletRequest implements HttpServletRequest {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private HttpSession session;
|
||||
private HttpSession session = new MockHttpSession();
|
||||
private Map headersMap = new HashMap();
|
||||
private Map paramMap = new HashMap();
|
||||
private Principal principal;
|
||||
|
||||
+404
@@ -0,0 +1,404 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
||||
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
|
||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import net.sf.acegisecurity.providers.cas.ticketvalidator.AbstractTicketValidator;
|
||||
import net.sf.acegisecurity.ui.cas.CasProcessingFilter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CasAuthenticationProvider}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasAuthenticationProviderTests extends TestCase {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public CasAuthenticationProviderTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CasAuthenticationProviderTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasAuthenticationProviderTests.class);
|
||||
}
|
||||
|
||||
public void testAuthenticateStateful() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(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");
|
||||
|
||||
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("marissa", casResult.getPrincipal());
|
||||
assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt",
|
||||
casResult.getProxyGrantingTicketIou());
|
||||
assertEquals("https://localhost/portal/j_acegi_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());
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
public void testAuthenticateStateless() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(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");
|
||||
|
||||
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("marissa", result.getPrincipal());
|
||||
assertEquals("ST-456", result.getCredentials());
|
||||
|
||||
// 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("marissa", newResult.getPrincipal());
|
||||
assertEquals("ST-456", newResult.getCredentials());
|
||||
}
|
||||
|
||||
public void testDetectsAMissingTicketId() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(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,
|
||||
"");
|
||||
|
||||
try {
|
||||
Authentication result = cap.authenticate(token);
|
||||
fail("Should have thrown BadCredentialsException");
|
||||
} catch (BadCredentialsException expected) {
|
||||
assertEquals("Failed to provide a CAS service ticket to validate",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsAnInvalidKey() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(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",
|
||||
"test", "credentials",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("XX")},
|
||||
new Vector(), "IOU-xxx");
|
||||
|
||||
try {
|
||||
Authentication result = cap.authenticate(token);
|
||||
fail("Should have thrown BadCredentialsException");
|
||||
} catch (BadCredentialsException expected) {
|
||||
assertEquals("The presented CasAuthenticationToken does not contain the expected key",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingAuthoritiesPopulator()
|
||||
throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasProxyDecider(new MockProxyDecider());
|
||||
cap.setKey("qwerty");
|
||||
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
||||
cap.setTicketValidator(new MockTicketValidator(true));
|
||||
|
||||
try {
|
||||
cap.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("A casAuthoritiesPopulator must be set",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingKey() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||
cap.setCasProxyDecider(new MockProxyDecider());
|
||||
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
||||
cap.setTicketValidator(new MockTicketValidator(true));
|
||||
|
||||
try {
|
||||
cap.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingProxyDecider() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||
cap.setKey("qwerty");
|
||||
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
||||
cap.setTicketValidator(new MockTicketValidator(true));
|
||||
|
||||
try {
|
||||
cap.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("A casProxyDecider must be set", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingStatelessTicketCache()
|
||||
throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||
cap.setCasProxyDecider(new MockProxyDecider());
|
||||
cap.setKey("qwerty");
|
||||
cap.setTicketValidator(new MockTicketValidator(true));
|
||||
|
||||
try {
|
||||
cap.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("A statelessTicketCache must be set",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingTicketValidator() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||
cap.setCasProxyDecider(new MockProxyDecider(true));
|
||||
cap.setKey("qwerty");
|
||||
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
||||
|
||||
try {
|
||||
cap.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("A ticketValidator must be set", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||
cap.setCasProxyDecider(new MockProxyDecider());
|
||||
cap.setKey("qwerty");
|
||||
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
||||
cap.setTicketValidator(new MockTicketValidator(true));
|
||||
cap.afterPropertiesSet();
|
||||
|
||||
assertTrue(cap.getCasAuthoritiesPopulator() != null);
|
||||
assertTrue(cap.getCasProxyDecider() != null);
|
||||
assertEquals("qwerty", cap.getKey());
|
||||
assertTrue(cap.getStatelessTicketCache() != null);
|
||||
assertTrue(cap.getTicketValidator() != null);
|
||||
}
|
||||
|
||||
public void testIgnoresClassesItDoesNotSupport() throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(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));
|
||||
}
|
||||
|
||||
public void testIgnoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal()
|
||||
throws Exception {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
cap.setCasAuthoritiesPopulator(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));
|
||||
}
|
||||
|
||||
public void testSupports() {
|
||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||
assertTrue(cap.supports(UsernamePasswordAuthenticationToken.class));
|
||||
assertTrue(cap.supports(CasAuthenticationToken.class));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==========================================================
|
||||
|
||||
private class MockAuthoritiesPopulator implements CasAuthoritiesPopulator {
|
||||
public GrantedAuthority[] getAuthorities(String casUserId)
|
||||
throws AuthenticationException {
|
||||
return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl(
|
||||
"ROLE_B")};
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private MockTicketValidator() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TicketResponse confirmTicketValid(String serviceTicket)
|
||||
throws AuthenticationException {
|
||||
if (returnTicket) {
|
||||
List list = new Vector();
|
||||
list.add("https://localhost/portal/j_acegi_cas_security_check");
|
||||
|
||||
return new TicketResponse("marissa", list,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
}
|
||||
|
||||
throw new BadCredentialsException("As requested from mock");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
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 final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasAuthenticationTokenTests.class);
|
||||
}
|
||||
|
||||
public void testConstructorRejectsNulls() {
|
||||
try {
|
||||
new CasAuthenticationToken(null, "Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, 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")}, new Vector(),
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new CasAuthenticationToken("key", "Test", null,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, new Vector(),
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new CasAuthenticationToken("key", "Test", "Password", null,
|
||||
new Vector(),
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new CasAuthenticationToken("key", "Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, null,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new CasAuthenticationToken("key", "Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, new Vector(), null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new CasAuthenticationToken("key", "Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), null, new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, 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_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token1 = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList1,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
|
||||
List proxyList2 = new Vector();
|
||||
proxyList2.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token2 = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, 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_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
assertEquals("key".hashCode(), token.getKeyHash());
|
||||
assertEquals("Test", 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());
|
||||
}
|
||||
|
||||
public void testNoArgConstructor() {
|
||||
try {
|
||||
new CasAuthenticationToken();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testNotEqualsDueToAbstractParentEqualsCheck() {
|
||||
List proxyList1 = new Vector();
|
||||
proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token1 = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList1,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
|
||||
List proxyList2 = new Vector();
|
||||
proxyList2.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token2 = new CasAuthenticationToken("key",
|
||||
"OTHER_VALUE", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList2,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
|
||||
assertTrue(!token1.equals(token2));
|
||||
}
|
||||
|
||||
public void testNotEqualsDueToDifferentAuthenticationClass() {
|
||||
List proxyList1 = new Vector();
|
||||
proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token1 = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList1,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
|
||||
UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test",
|
||||
"Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
token2.setAuthenticated(true);
|
||||
|
||||
assertTrue(!token1.equals(token2));
|
||||
}
|
||||
|
||||
public void testNotEqualsDueToProxyGrantingTicket() {
|
||||
List proxyList1 = new Vector();
|
||||
proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token1 = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList1,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
|
||||
List proxyList2 = new Vector();
|
||||
proxyList2.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token2 = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList2, "PGTIOU-SOME_OTHER_VALUE");
|
||||
|
||||
assertTrue(!token1.equals(token2));
|
||||
}
|
||||
|
||||
public void testNotEqualsDueToProxyList() {
|
||||
List proxyList1 = new Vector();
|
||||
proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token1 = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList1,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
|
||||
List proxyList2 = new Vector();
|
||||
proxyList2.add(
|
||||
"https://localhost/SOME_OTHER_PORTAL/j_acegi_cas_security_check");
|
||||
|
||||
CasAuthenticationToken token2 = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList2,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
|
||||
assertTrue(!token1.equals(token2));
|
||||
}
|
||||
|
||||
public void testSetAuthenticatedIgnored() {
|
||||
CasAuthenticationToken token = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, new Vector(),
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
assertTrue(token.isAuthenticated());
|
||||
token.setAuthenticated(false); // ignored
|
||||
assertTrue(token.isAuthenticated());
|
||||
}
|
||||
|
||||
public void testToString() {
|
||||
CasAuthenticationToken token = new CasAuthenticationToken("key",
|
||||
"Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, 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 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 net.sf.acegisecurity.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 final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(TicketResponseTests.class);
|
||||
}
|
||||
|
||||
public void testConstructorAcceptsNullProxyGrantingTicketIOU() {
|
||||
TicketResponse ticket = new TicketResponse("marissa", new Vector(), null);
|
||||
assertEquals("", ticket.getProxyGrantingTicketIou());
|
||||
}
|
||||
|
||||
public void testConstructorAcceptsNullProxyList() {
|
||||
TicketResponse ticket = new TicketResponse("marissa", 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_acegi_cas_security_check");
|
||||
|
||||
TicketResponse ticket = new TicketResponse("marissa", proxyList,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
assertEquals("marissa", ticket.getUser());
|
||||
assertEquals(proxyList, ticket.getProxyList());
|
||||
assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt",
|
||||
ticket.getProxyGrantingTicketIou());
|
||||
}
|
||||
|
||||
public void testNoArgConstructor() {
|
||||
try {
|
||||
new TicketResponse();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testToString() {
|
||||
TicketResponse ticket = new TicketResponse("marissa", 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);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.cache;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
||||
import net.sf.acegisecurity.providers.cas.CasAuthenticationToken;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link EhCacheBasedTicketCache}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EhCacheBasedTicketCacheTests extends TestCase {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public EhCacheBasedTicketCacheTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public EhCacheBasedTicketCacheTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(EhCacheBasedTicketCacheTests.class);
|
||||
}
|
||||
|
||||
public void testCacheOperation() throws Exception {
|
||||
EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
|
||||
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"));
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
|
||||
cache.setMinutesToIdle(5);
|
||||
assertEquals(5, cache.getMinutesToIdle());
|
||||
}
|
||||
|
||||
private CasAuthenticationToken getToken() {
|
||||
List proxyList = new Vector();
|
||||
proxyList.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
return new CasAuthenticationToken("key", "marissa",
|
||||
"ST-0-ER94xMJmn6pha35CQRoZ",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")}, proxyList,
|
||||
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
|
||||
}
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.populator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
||||
import net.sf.acegisecurity.providers.dao.AuthenticationDao;
|
||||
import net.sf.acegisecurity.providers.dao.User;
|
||||
import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link DaoCasAuthoritiesPopulator}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class DaoCasAuthoritiesPopulatorTests extends TestCase {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public DaoCasAuthoritiesPopulatorTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public DaoCasAuthoritiesPopulatorTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(DaoCasAuthoritiesPopulatorTests.class);
|
||||
}
|
||||
|
||||
public void testDetectsMissingAuthenticationDao() throws Exception {
|
||||
DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator();
|
||||
|
||||
try {
|
||||
populator.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("An authenticationDao must be set",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetGrantedAuthoritiesForInvalidUsername()
|
||||
throws Exception {
|
||||
DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator();
|
||||
populator.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||
populator.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
populator.getAuthorities("scott");
|
||||
fail("Should have thrown UsernameNotFoundException");
|
||||
} catch (UsernameNotFoundException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetGrantedAuthoritiesForValidUsername()
|
||||
throws Exception {
|
||||
DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator();
|
||||
populator.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||
populator.afterPropertiesSet();
|
||||
|
||||
GrantedAuthority[] results = populator.getAuthorities("marissa");
|
||||
assertEquals(2, results.length);
|
||||
assertEquals(new GrantedAuthorityImpl("ROLE_ONE"), results[0]);
|
||||
assertEquals(new GrantedAuthorityImpl("ROLE_TWO"), results[1]);
|
||||
}
|
||||
|
||||
public void testGetGrantedAuthoritiesWhenDaoThrowsException()
|
||||
throws Exception {
|
||||
DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator();
|
||||
populator.setAuthenticationDao(new MockAuthenticationDaoSimulateBackendError());
|
||||
populator.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
populator.getAuthorities("THE_DAO_WILL_FAIL");
|
||||
fail("Should have thrown DataRetrievalFailureException");
|
||||
} catch (DataRetrievalFailureException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator();
|
||||
AuthenticationDao dao = new MockAuthenticationDaoUserMarissa();
|
||||
populator.setAuthenticationDao(dao);
|
||||
assertEquals(dao, populator.getAuthenticationDao());
|
||||
}
|
||||
|
||||
//~ Inner Classes ==========================================================
|
||||
|
||||
private class MockAuthenticationDaoSimulateBackendError
|
||||
implements AuthenticationDao {
|
||||
public long getRefreshDuration() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public User loadUserByUsername(String username)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
throw new DataRetrievalFailureException(
|
||||
"This mock simulator is designed to fail");
|
||||
}
|
||||
}
|
||||
|
||||
private class MockAuthenticationDaoUserMarissa implements AuthenticationDao {
|
||||
public long getRefreshDuration() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public User loadUserByUsername(String username)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("marissa".equals(username)) {
|
||||
return new User("marissa", "koala", true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: "
|
||||
+ username);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/* 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 net.sf.acegisecurity.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 final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(AcceptAnyCasProxyTests.class);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.proxy;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.providers.cas.ProxyUntrustedException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link NamedCasProxyDecider}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class NamedCasProxyDeciderTests extends TestCase {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public NamedCasProxyDeciderTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public NamedCasProxyDeciderTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(NamedCasProxyDeciderTests.class);
|
||||
}
|
||||
|
||||
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_acegi_cas_security_check");
|
||||
|
||||
// Build the list of valid nearest proxies
|
||||
List validProxies = new Vector();
|
||||
validProxies.add("https://localhost/portal/j_acegi_cas_security_check");
|
||||
validProxies.add(
|
||||
"https://localhost/newPortal/j_acegi_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_acegi_cas_security_check");
|
||||
validProxies.add(
|
||||
"https://localhost/newPortal/j_acegi_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_acegi_cas_security_check");
|
||||
|
||||
// Build the list of valid nearest proxies
|
||||
List validProxies = new Vector();
|
||||
validProxies.add("https://localhost/portal/j_acegi_cas_security_check");
|
||||
validProxies.add(
|
||||
"https://localhost/newPortal/j_acegi_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 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 net.sf.acegisecurity.providers.cas.proxy;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.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 final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(RejectProxyTicketsTests.class);
|
||||
}
|
||||
|
||||
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_acegi_cas_security_check");
|
||||
|
||||
try {
|
||||
proxyDecider.confirmProxyListTrusted(proxyList);
|
||||
fail("Should have thrown ProxyUntrustedException");
|
||||
} catch (ProxyUntrustedException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.ticketvalidator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.providers.cas.TicketResponse;
|
||||
import net.sf.acegisecurity.ui.cas.ServiceProperties;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link AbstractTicketValidator}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AbstractTicketValidatorTests extends TestCase {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public AbstractTicketValidatorTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AbstractTicketValidatorTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(AbstractTicketValidatorTests.class);
|
||||
}
|
||||
|
||||
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 testSystemPropertySetDuringAfterPropertiesSet()
|
||||
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.setTrustStore("/some/file/cacerts");
|
||||
assertEquals("/some/file/cacerts", tv.getTrustStore());
|
||||
|
||||
String before = System.getProperty("javax.net.ssl.trustStore");
|
||||
tv.afterPropertiesSet();
|
||||
assertEquals("/some/file/cacerts",
|
||||
System.getProperty("javax.net.ssl.trustStore"));
|
||||
|
||||
if (before == null) {
|
||||
System.setProperty("javax.net.ssl.trustStore", "");
|
||||
} else {
|
||||
System.setProperty("javax.net.ssl.trustStore", before);
|
||||
}
|
||||
}
|
||||
|
||||
//~ Inner Classes ==========================================================
|
||||
|
||||
private class MockAbstractTicketValidator extends AbstractTicketValidator {
|
||||
private boolean returnTicket;
|
||||
|
||||
public MockAbstractTicketValidator(boolean returnTicket) {
|
||||
this.returnTicket = returnTicket;
|
||||
}
|
||||
|
||||
private MockAbstractTicketValidator() {
|
||||
super();
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/* 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 net.sf.acegisecurity.providers.cas.ticketvalidator;
|
||||
|
||||
import edu.yale.its.tp.cas.client.ProxyTicketValidator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.AuthenticationServiceException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.providers.cas.TicketResponse;
|
||||
import net.sf.acegisecurity.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 final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasProxyTicketValidatorTests.class);
|
||||
}
|
||||
|
||||
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_acegi_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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/* 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 net.sf.acegisecurity.ui.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.MockHttpServletRequest;
|
||||
import net.sf.acegisecurity.MockHttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CasProcessingFilterEntryPoint}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasProcessingFilterEntryPointTests extends TestCase {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public CasProcessingFilterEntryPointTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CasProcessingFilterEntryPointTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasProcessingFilterEntryPointTests.class);
|
||||
}
|
||||
|
||||
public void testDetectsMissingLoginFormUrl() throws Exception {
|
||||
CasProcessingFilterEntryPoint ep = new CasProcessingFilterEntryPoint();
|
||||
ep.setServiceProperties(new ServiceProperties());
|
||||
|
||||
try {
|
||||
ep.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("loginUrl must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingServiceProperties() throws Exception {
|
||||
CasProcessingFilterEntryPoint ep = new CasProcessingFilterEntryPoint();
|
||||
ep.setLoginUrl("https://cas/login");
|
||||
|
||||
try {
|
||||
ep.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("serviceProperties must be specified",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
CasProcessingFilterEntryPoint ep = new CasProcessingFilterEntryPoint();
|
||||
ep.setLoginUrl("https://cas/login");
|
||||
assertEquals("https://cas/login", ep.getLoginUrl());
|
||||
|
||||
ep.setServiceProperties(new ServiceProperties());
|
||||
assertTrue(ep.getServiceProperties() != null);
|
||||
}
|
||||
|
||||
public void testNormalOperationWithRenewFalse() throws Exception {
|
||||
ServiceProperties sp = new ServiceProperties();
|
||||
sp.setSendRenew(false);
|
||||
sp.setService(
|
||||
"https://mycompany.com/bigWebApp/j_acegi_cas_security_check");
|
||||
|
||||
CasProcessingFilterEntryPoint ep = new CasProcessingFilterEntryPoint();
|
||||
ep.setLoginUrl("https://cas/login");
|
||||
ep.setServiceProperties(sp);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(
|
||||
"/some_path");
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
ep.afterPropertiesSet();
|
||||
ep.commence(request, response);
|
||||
assertEquals("https://cas/login?service=https://mycompany.com/bigWebApp/j_acegi_cas_security_check",
|
||||
response.getRedirect());
|
||||
}
|
||||
|
||||
public void testNormalOperationWithRenewTrue() throws Exception {
|
||||
ServiceProperties sp = new ServiceProperties();
|
||||
sp.setSendRenew(true);
|
||||
sp.setService(
|
||||
"https://mycompany.com/bigWebApp/j_acegi_cas_security_check");
|
||||
|
||||
CasProcessingFilterEntryPoint ep = new CasProcessingFilterEntryPoint();
|
||||
ep.setLoginUrl("https://cas/login");
|
||||
ep.setServiceProperties(sp);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(
|
||||
"/some_path");
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
ep.afterPropertiesSet();
|
||||
ep.commence(request, response);
|
||||
assertEquals("https://cas/login?renew=true&service=https://mycompany.com/bigWebApp/j_acegi_cas_security_check",
|
||||
response.getRedirect());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/* 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 net.sf.acegisecurity.ui.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.MockAuthenticationManager;
|
||||
import net.sf.acegisecurity.MockHttpServletRequest;
|
||||
import net.sf.acegisecurity.MockHttpSession;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CasProcessingFilter}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasProcessingFilterTests extends TestCase {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public CasProcessingFilterTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CasProcessingFilterTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasProcessingFilterTests.class);
|
||||
}
|
||||
|
||||
public void testGetters() {
|
||||
CasProcessingFilter filter = new CasProcessingFilter();
|
||||
assertEquals("/j_acegi_cas_security_check",
|
||||
filter.getDefaultFilterProcessesUrl());
|
||||
}
|
||||
|
||||
public void testNormalOperation() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(null,
|
||||
new MockHttpSession());
|
||||
request.setParameter("ticket", "ST-0-ER94xMJmn6pha35CQRoZ");
|
||||
|
||||
MockAuthenticationManager authMgr = new MockAuthenticationManager(true);
|
||||
|
||||
CasProcessingFilter filter = new CasProcessingFilter();
|
||||
filter.setAuthenticationManager(authMgr);
|
||||
filter.init(null);
|
||||
|
||||
Authentication result = filter.attemptAuthentication(request);
|
||||
assertTrue(result != null);
|
||||
}
|
||||
|
||||
public void testNullServiceTicketHandledGracefully()
|
||||
throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(null,
|
||||
new MockHttpSession());
|
||||
|
||||
MockAuthenticationManager authMgr = new MockAuthenticationManager(false);
|
||||
|
||||
CasProcessingFilter filter = new CasProcessingFilter();
|
||||
filter.setAuthenticationManager(authMgr);
|
||||
filter.init(null);
|
||||
|
||||
try {
|
||||
filter.attemptAuthentication(request);
|
||||
fail("Should have thrown AuthenticationException");
|
||||
} catch (AuthenticationException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/* 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 net.sf.acegisecurity.ui.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link ServiceProperties}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ServicePropertiesTests extends TestCase {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public ServicePropertiesTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ServicePropertiesTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(ServicePropertiesTests.class);
|
||||
}
|
||||
|
||||
public void testDetectsMissingLoginFormUrl() throws Exception {
|
||||
ServiceProperties sp = new ServiceProperties();
|
||||
|
||||
try {
|
||||
sp.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("service must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() throws Exception {
|
||||
ServiceProperties sp = new ServiceProperties();
|
||||
sp.setSendRenew(false);
|
||||
assertFalse(sp.isSendRenew());
|
||||
sp.setSendRenew(true);
|
||||
assertTrue(sp.isSendRenew());
|
||||
|
||||
sp.setService("https://mycompany.com/service");
|
||||
assertEquals("https://mycompany.com/service", sp.getService());
|
||||
|
||||
sp.afterPropertiesSet();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user