SEC-97: Format Acegi Security source code in accordance with latest Jalopy configuration.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,27 +17,21 @@ package org.acegisecurity;
|
||||
|
||||
import org.acegisecurity.providers.AbstractAuthenticationToken;
|
||||
|
||||
|
||||
/**
|
||||
* An abstract implementation of the {@link AuthenticationManager}.
|
||||
*
|
||||
* @author Wesley Hall
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractAuthenticationManager
|
||||
implements AuthenticationManager {
|
||||
//~ Methods ================================================================
|
||||
public abstract class AbstractAuthenticationManager implements AuthenticationManager {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* An implementation of the <code>authenticate</code> method that calls the
|
||||
* abstract method <code>doAuthenticatation</code> to do its work.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If doAuthenticate throws an <code>AuthenticationException</code> then
|
||||
* the exception is populated with the failed <code>Authentication</code>
|
||||
* object that failed.
|
||||
* </p>
|
||||
* <p>An implementation of the <code>authenticate</code> method that calls the abstract method
|
||||
* <code>doAuthenticatation</code> to do its work.</p>
|
||||
* <p>If doAuthenticate throws an <code>AuthenticationException</code> then the exception is populated
|
||||
* with the failed <code>Authentication</code> object that failed.</p>
|
||||
*
|
||||
* @param authRequest the authentication request object
|
||||
*
|
||||
@@ -59,32 +53,24 @@ public abstract class AbstractAuthenticationManager
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the authentication details from a source Authentication object
|
||||
* to a destination one, provided the latter does not already have one
|
||||
* set.
|
||||
* Copies the authentication details from a source Authentication object to a destination one, provided the
|
||||
* latter does not already have one set.
|
||||
*
|
||||
* @param source source authentication
|
||||
* @param dest the destination authentication object
|
||||
*/
|
||||
private void copyDetails(Authentication source, Authentication dest) {
|
||||
if((dest instanceof AbstractAuthenticationToken)
|
||||
&& dest.getDetails() == null) {
|
||||
AbstractAuthenticationToken token = (AbstractAuthenticationToken)dest;
|
||||
if ((dest instanceof AbstractAuthenticationToken) && (dest.getDetails() == null)) {
|
||||
AbstractAuthenticationToken token = (AbstractAuthenticationToken) dest;
|
||||
|
||||
token.setDetails(source.getDetails());
|
||||
token.setDetails(source.getDetails());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Concrete implementations of this class override this method to provide
|
||||
* the authentication service.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The contract for this method is documented in the {@link
|
||||
* AuthenticationManager#authenticate(org.acegisecurity.Authentication)}.
|
||||
* </p>
|
||||
* <p>Concrete implementations of this class override this method to provide the authentication service.</p>
|
||||
* <p>The contract for this method is documented in the {@link
|
||||
* AuthenticationManager#authenticate(org.acegisecurity.Authentication)}.</p>
|
||||
*
|
||||
* @param authentication the authentication request object
|
||||
*
|
||||
@@ -92,6 +78,6 @@ public abstract class AbstractAuthenticationManager
|
||||
*
|
||||
* @throws AuthenticationException if authentication fails
|
||||
*/
|
||||
protected abstract Authentication doAuthentication(
|
||||
Authentication authentication) throws AuthenticationException;
|
||||
protected abstract Authentication doAuthentication(Authentication authentication)
|
||||
throws AuthenticationException;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,54 +22,44 @@ package org.acegisecurity;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AccessDecisionManager {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Resolves an access control decision for the passed parameters.
|
||||
*
|
||||
* @param authentication the caller invoking the method
|
||||
* @param object the secured object being called
|
||||
* @param config the configuration attributes associated with the secured
|
||||
* object being invoked
|
||||
* @param config the configuration attributes associated with the secured object being invoked
|
||||
*
|
||||
* @throws AccessDeniedException if access is denied as the authentication
|
||||
* does not hold a required authority or ACL privilege
|
||||
* @throws InsufficientAuthenticationException if access is denied as the
|
||||
* authentication does not provide a sufficient level of trust
|
||||
* @throws AccessDeniedException if access is denied as the authentication does not hold a required authority or
|
||||
* ACL privilege
|
||||
* @throws InsufficientAuthenticationException if access is denied as the authentication does not provide a
|
||||
* sufficient level of trust
|
||||
*/
|
||||
public void decide(Authentication authentication, Object object,
|
||||
ConfigAttributeDefinition config)
|
||||
public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config)
|
||||
throws AccessDeniedException, InsufficientAuthenticationException;
|
||||
|
||||
/**
|
||||
* Indicates whether this <code>AccessDecisionManager</code> is able to
|
||||
* process authorization requests presented with the passed
|
||||
* <code>ConfigAttribute</code>.
|
||||
*
|
||||
* <p>
|
||||
* This allows the <code>AbstractSecurityInterceptor</code> to check every
|
||||
* configuration attribute can be consumed by the configured
|
||||
* <code>AccessDecisionManager</code> and/or <code>RunAsManager</code>
|
||||
* and/or <code>AfterInvocationManager</code>.
|
||||
* </p>
|
||||
* Indicates whether this <code>AccessDecisionManager</code> is able to process authorization requests
|
||||
* presented with the passed <code>ConfigAttribute</code>.<p>This allows the
|
||||
* <code>AbstractSecurityInterceptor</code> to check every configuration attribute can be consumed by the
|
||||
* configured <code>AccessDecisionManager</code> and/or <code>RunAsManager</code> and/or
|
||||
* <code>AfterInvocationManager</code>.</p>
|
||||
*
|
||||
* @param attribute a configuration attribute that has been configured
|
||||
* against the <code>AbstractSecurityInterceptor</code>
|
||||
* @param attribute a configuration attribute that has been configured against the
|
||||
* <code>AbstractSecurityInterceptor</code>
|
||||
*
|
||||
* @return true if this <code>AccessDecisionManager</code> can support the
|
||||
* passed configuration attribute
|
||||
* @return true if this <code>AccessDecisionManager</code> can support the passed configuration attribute
|
||||
*/
|
||||
public boolean supports(ConfigAttribute attribute);
|
||||
|
||||
/**
|
||||
* Indicates whether the <code>AccessDecisionManager</code> implementation
|
||||
* is able to provide access control decisions for the indicated secured
|
||||
* object type.
|
||||
* Indicates whether the <code>AccessDecisionManager</code> implementation is able to provide access
|
||||
* control decisions for the indicated secured object type.
|
||||
*
|
||||
* @param clazz the class that is being queried
|
||||
*
|
||||
* @return <code>true</code> if the implementation can process the
|
||||
* indicated class
|
||||
* @return <code>true</code> if the implementation can process the indicated class
|
||||
*/
|
||||
public boolean supports(Class clazz);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,16 +16,15 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an {@link Authentication} object does not hold a required
|
||||
* authority.
|
||||
* Thrown if an {@link Authentication} object does not hold a required authority.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AccessDeniedException extends AcegiSecurityException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AccessDeniedException</code> with the specified
|
||||
* message.
|
||||
*
|
||||
@@ -35,7 +34,7 @@ public class AccessDeniedException extends AcegiSecurityException {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AccessDeniedException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,17 +16,16 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because the account has
|
||||
* expired. Makes no assertion as to whether or not the credentials were
|
||||
* valid.
|
||||
* Thrown if an authentication request is rejected because the account has expired. Makes no assertion as to
|
||||
* whether or not the credentials were valid.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AccountExpiredException extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>AccountExpiredException</code> with the specified
|
||||
* message.
|
||||
*
|
||||
@@ -36,7 +35,7 @@ public class AccountExpiredException extends AuthenticationException {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>AccountExpiredException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
|
||||
@@ -20,27 +20,22 @@ import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
|
||||
|
||||
/**
|
||||
* The default <code>MessageSource</code> used by Acegi Security.
|
||||
*
|
||||
* <p>
|
||||
* All Acegi Security classes requiring messge localization will by default use
|
||||
* this class. However, all such classes will also implement
|
||||
* <code>MessageSourceAware</code> so that the application context can inject
|
||||
* an alternative message source. Therefore this class is only used when the
|
||||
* deployment environment has not specified an alternative message source.
|
||||
* </p>
|
||||
* The default <code>MessageSource</code> used by Acegi Security.<p>All Acegi Security classes requiring messge
|
||||
* localization will by default use this class. However, all such classes will also implement
|
||||
* <code>MessageSourceAware</code> so that the application context can inject an alternative message source. Therefore
|
||||
* this class is only used when the deployment environment has not specified an alternative message source.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AcegiMessageSource extends ResourceBundleMessageSource {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AcegiMessageSource() {
|
||||
setBasename("org.acegisecurity.messages");
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static MessageSourceAccessor getAccessor() {
|
||||
return new MessageSourceAccessor(new AcegiMessageSource());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,21 +19,16 @@ import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract superclass for all exceptions thrown in the security package and
|
||||
* subpackages.
|
||||
*
|
||||
* <p>
|
||||
* Note that this is a runtime (unchecked) exception. Security exceptions are
|
||||
* usually fatal; there is no reason for them to be checked.
|
||||
* </p>
|
||||
* Abstract superclass for all exceptions thrown in the security package and subpackages.<p>Note that this is a
|
||||
* runtime (unchecked) exception. Security exceptions are usually fatal; there is no reason for them to be checked.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AcegiSecurityException extends NestedRuntimeException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AcegiSecurityException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
@@ -44,7 +39,7 @@ public abstract class AcegiSecurityException extends NestedRuntimeException {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AcegiSecurityException</code> with the specified
|
||||
* message and no root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,61 +43,47 @@ package org.acegisecurity;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AfterInvocationManager {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Given the details of a secure object invocation including its returned
|
||||
* <code>Object</code>, make an access control decision or optionally
|
||||
* modify the returned <code>Object</code>.
|
||||
* Given the details of a secure object invocation including its returned <code>Object</code>, make an
|
||||
* access control decision or optionally modify the returned <code>Object</code>.
|
||||
*
|
||||
* @param authentication the caller that invoked the method
|
||||
* @param object the secured object that was called
|
||||
* @param config the configuration attributes associated with the secured
|
||||
* object that was invoked
|
||||
* @param returnedObject the <code>Object</code> that was returned from the
|
||||
* secure object invocation
|
||||
* @param config the configuration attributes associated with the secured object that was invoked
|
||||
* @param returnedObject the <code>Object</code> that was returned from the secure object invocation
|
||||
*
|
||||
* @return the <code>Object</code> that will ultimately be returned to the
|
||||
* caller (if an implementation does not wish to modify the object
|
||||
* to be returned to the caller, the implementation should simply
|
||||
* return the same object it was passed by the
|
||||
* <code>returnedObject</code> method argument)
|
||||
* @return the <code>Object</code> that will ultimately be returned to the caller (if an implementation does not
|
||||
* wish to modify the object to be returned to the caller, the implementation should simply return the
|
||||
* same object it was passed by the <code>returnedObject</code> method argument)
|
||||
*
|
||||
* @throws AccessDeniedException if access is denied
|
||||
*/
|
||||
public Object decide(Authentication authentication, Object object,
|
||||
ConfigAttributeDefinition config, Object returnedObject)
|
||||
throws AccessDeniedException;
|
||||
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
|
||||
Object returnedObject) throws AccessDeniedException;
|
||||
|
||||
/**
|
||||
* Indicates whether this <code>AfterInvocationManager</code> is able to
|
||||
* process "after invocation" requests presented with the passed
|
||||
* <code>ConfigAttribute</code>.
|
||||
*
|
||||
* <p>
|
||||
* This allows the <code>AbstractSecurityInterceptor</code> to check every
|
||||
* configuration attribute can be consumed by the configured
|
||||
* <code>AccessDecisionManager</code> and/or <code>RunAsManager</code>
|
||||
* and/or <code>AfterInvocationManager</code>.
|
||||
* </p>
|
||||
* Indicates whether this <code>AfterInvocationManager</code> is able to process "after invocation"
|
||||
* requests presented with the passed <code>ConfigAttribute</code>.<p>This allows the
|
||||
* <code>AbstractSecurityInterceptor</code> to check every configuration attribute can be consumed by the
|
||||
* configured <code>AccessDecisionManager</code> and/or <code>RunAsManager</code> and/or
|
||||
* <code>AfterInvocationManager</code>.</p>
|
||||
*
|
||||
* @param attribute a configuration attribute that has been configured
|
||||
* against the <code>AbstractSecurityInterceptor</code>
|
||||
* @param attribute a configuration attribute that has been configured against the
|
||||
* <code>AbstractSecurityInterceptor</code>
|
||||
*
|
||||
* @return true if this <code>AfterInvocationManager</code> can support the
|
||||
* passed configuration attribute
|
||||
* @return true if this <code>AfterInvocationManager</code> can support the passed configuration attribute
|
||||
*/
|
||||
public boolean supports(ConfigAttribute attribute);
|
||||
|
||||
/**
|
||||
* Indicates whether the <code>AfterInvocationManager</code> implementation
|
||||
* is able to provide access control decisions for the indicated secured
|
||||
* object type.
|
||||
* Indicates whether the <code>AfterInvocationManager</code> implementation is able to provide access
|
||||
* control decisions for the indicated secured object type.
|
||||
*
|
||||
* @param clazz the class that is being queried
|
||||
*
|
||||
* @return <code>true</code> if the implementation can process the
|
||||
* indicated class
|
||||
* @return <code>true</code> if the implementation can process the indicated class
|
||||
*/
|
||||
public boolean supports(Class clazz);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,101 +37,71 @@ import java.security.Principal;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface Authentication extends Principal, Serializable {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* See {@link #isAuthenticated()} for a full description.
|
||||
*
|
||||
* <p>
|
||||
* Implementations should <b>always</b> allow this method to be called with
|
||||
* a <code>false</code> parameter, as this is used by various classes to
|
||||
* specify the authentication token should not be trusted. If an
|
||||
* implementation wishes to reject an invocation with a <code>true</code>
|
||||
* parameter (which would indicate the authentication token is trusted - a
|
||||
* potential security risk) the implementation should throw an {@link
|
||||
* IllegalArgumentException}.
|
||||
* </p>
|
||||
* Set by an <code>AuthenticationManager</code> to indicate the authorities that the principal has been
|
||||
* granted. Note that classes should not rely on this value as being valid unless it has been set by a trusted
|
||||
* <code>AuthenticationManager</code>.<p>Implementations should ensure that modifications to the returned
|
||||
* array do not affect the state of the Authentication object (e.g. by returning an array copy).</p>
|
||||
*
|
||||
* @param isAuthenticated <code>true</code> if the token should be trusted
|
||||
* (which may result in an exception) or <code>false</code> if the
|
||||
* token should not be trusted
|
||||
*
|
||||
* @throws IllegalArgumentException if an attempt to make the
|
||||
* authentication token trusted (by passing <code>true</code> as
|
||||
* the argument) is rejected due to the implementation being
|
||||
* immutable or implementing its own alternative approach to
|
||||
* {@link #isAuthenticated()}
|
||||
*/
|
||||
public void setAuthenticated(boolean isAuthenticated)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Used to indicate to <code>AbstractSecurityInterceptor</code> whether it
|
||||
* should present the authentication token to the
|
||||
* <code>AuthenticationManager</code>. Typically an
|
||||
* <code>AuthenticationManager</code> (or, more often, one of its
|
||||
* <code>AuthenticationProvider</code>s) will return an immutable
|
||||
* authentication token after successful authentication, in which case
|
||||
* that token can safely return <code>true</code> to this method.
|
||||
* Returning <code>true</code> will improve performance, as calling the
|
||||
* <code>AuthenticationManager</code> for every request will no longer be
|
||||
* necessary.
|
||||
*
|
||||
* <p>
|
||||
* For security reasons, implementations of this interface should be very
|
||||
* careful about returning <code>true</code> to this method unless they
|
||||
* are either immutable, or have some way of ensuring the properties have
|
||||
* not been changed since original creation.
|
||||
* </p>
|
||||
*
|
||||
* @return true if the token has been authenticated and the
|
||||
* <code>AbstractSecurityInterceptor</code> does not need to
|
||||
* represent the token for re-authentication to the
|
||||
* <code>AuthenticationManager</code>
|
||||
*/
|
||||
public boolean isAuthenticated();
|
||||
|
||||
/**
|
||||
* Set by an <code>AuthenticationManager</code> to indicate the authorities
|
||||
* that the principal has been granted. Note that classes should not rely
|
||||
* on this value as being valid unless it has been set by a trusted
|
||||
* <code>AuthenticationManager</code>.
|
||||
* <p>
|
||||
* Implementations should ensure that modifications to the returned array
|
||||
* do not affect the state of the Authentication object (e.g. by returning an
|
||||
* array copy).
|
||||
* </p>
|
||||
*
|
||||
* @return the authorities granted to the principal, or <code>null</code>
|
||||
* if authentication has not been completed
|
||||
* @return the authorities granted to the principal, or <code>null</code> if authentication has not been completed
|
||||
*/
|
||||
public GrantedAuthority[] getAuthorities();
|
||||
|
||||
/**
|
||||
* The credentials that prove the principal is correct. This is usually a
|
||||
* password, but could be anything relevant to the
|
||||
* <code>AuthenticationManager</code>. Callers are expected to populate
|
||||
* the credentials.
|
||||
* The credentials that prove the principal is correct. This is usually a password, but could be anything
|
||||
* relevant to the <code>AuthenticationManager</code>. Callers are expected to populate the credentials.
|
||||
*
|
||||
* @return the credentials that prove the identity of the
|
||||
* <code>Principal</code>
|
||||
* @return the credentials that prove the identity of the <code>Principal</code>
|
||||
*/
|
||||
public Object getCredentials();
|
||||
|
||||
/**
|
||||
* Stores additional details about the authentication request. These might
|
||||
* be an IP address, certificate serial number etc.
|
||||
* Stores additional details about the authentication request. These might be an IP address, certificate
|
||||
* serial number etc.
|
||||
*
|
||||
* @return additional details about the authentication request, or
|
||||
* <code>null</code> if not used
|
||||
* @return additional details about the authentication request, or <code>null</code> if not used
|
||||
*/
|
||||
public Object getDetails();
|
||||
|
||||
/**
|
||||
* The identity of the principal being authenticated. This is usually a
|
||||
* username. Callers are expected to populate the principal.
|
||||
* The identity of the principal being authenticated. This is usually a username. Callers are expected to
|
||||
* populate the principal.
|
||||
*
|
||||
* @return the <code>Principal</code> being authenticated
|
||||
*/
|
||||
public Object getPrincipal();
|
||||
|
||||
/**
|
||||
* Used to indicate to <code>AbstractSecurityInterceptor</code> whether it should present the
|
||||
* authentication token to the <code>AuthenticationManager</code>. Typically an <code>AuthenticationManager</code>
|
||||
* (or, more often, one of its <code>AuthenticationProvider</code>s) will return an immutable authentication token
|
||||
* after successful authentication, in which case that token can safely return <code>true</code> to this method.
|
||||
* Returning <code>true</code> will improve performance, as calling the <code>AuthenticationManager</code> for
|
||||
* every request will no longer be necessary.<p>For security reasons, implementations of this interface
|
||||
* should be very careful about returning <code>true</code> to this method unless they are either immutable, or
|
||||
* have some way of ensuring the properties have not been changed since original creation.</p>
|
||||
*
|
||||
* @return true if the token has been authenticated and the <code>AbstractSecurityInterceptor</code> does not need
|
||||
* to represent the token for re-authentication to the <code>AuthenticationManager</code>
|
||||
*/
|
||||
public boolean isAuthenticated();
|
||||
|
||||
/**
|
||||
* See {@link #isAuthenticated()} for a full description.<p>Implementations should <b>always</b> allow this
|
||||
* method to be called with a <code>false</code> parameter, as this is used by various classes to specify the
|
||||
* authentication token should not be trusted. If an implementation wishes to reject an invocation with a
|
||||
* <code>true</code> parameter (which would indicate the authentication token is trusted - a potential security
|
||||
* risk) the implementation should throw an {@link IllegalArgumentException}.</p>
|
||||
*
|
||||
* @param isAuthenticated <code>true</code> if the token should be trusted (which may result in an exception) or
|
||||
* <code>false</code> if the token should not be trusted
|
||||
*
|
||||
* @throws IllegalArgumentException if an attempt to make the authentication token trusted (by passing
|
||||
* <code>true</code> as the argument) is rejected due to the implementation being immutable or
|
||||
* implementing its own alternative approach to {@link #isAuthenticated()}
|
||||
*/
|
||||
public void setAuthenticated(boolean isAuthenticated)
|
||||
throws IllegalArgumentException;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,17 +16,16 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because there is no {@link
|
||||
* Authentication} object in the {@link org.acegisecurity.context.SecurityContext SecurityContext}.
|
||||
* Thrown if an authentication request is rejected because there is no {@link Authentication} object in the {@link
|
||||
* org.acegisecurity.context.SecurityContext SecurityContext}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationCredentialsNotFoundException
|
||||
extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationCredentialsNotFoundException extends AuthenticationException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AuthenticationCredentialsNotFoundException</code>
|
||||
* with the specified message.
|
||||
*
|
||||
@@ -36,7 +35,7 @@ public class AuthenticationCredentialsNotFoundException
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AuthenticationCredentialsNotFoundException</code>
|
||||
* with the specified message and root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,24 +16,21 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Abstract superclass for all exceptions related an {@link Authentication}
|
||||
* object being invalid for whatever reason.
|
||||
* Abstract superclass for all exceptions related an {@link Authentication} object being invalid for whatever
|
||||
* reason.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AuthenticationException extends AcegiSecurityException {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
/**
|
||||
* The authentication that related to this exception (may be
|
||||
* <code>null</code>)
|
||||
*/
|
||||
/** The authentication that related to this exception (may be <code>null</code>) */
|
||||
private Authentication authentication;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AuthenticationException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
@@ -44,7 +41,7 @@ public abstract class AuthenticationException extends AcegiSecurityException {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AuthenticationException</code> with the specified
|
||||
* message and no root cause.
|
||||
*
|
||||
@@ -54,7 +51,7 @@ public abstract class AuthenticationException extends AcegiSecurityException {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Authentication getAuthentication() {
|
||||
return authentication;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,41 +22,21 @@ package org.acegisecurity;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AuthenticationManager {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Attempts to authenticate the passed {@link Authentication} object,
|
||||
* returning a fully populated <code>Authentication</code> object
|
||||
* (including granted authorities) if successful.
|
||||
*
|
||||
* <p>
|
||||
* An <code>AuthenticationManager</code> must honour the following contract
|
||||
* concerning exceptions:
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* A {@link DisabledException} must be thrown if an account is disabled and
|
||||
* the <code>AuthenticationManager</code> can test for this state.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* A {@link LockedException} must be thrown if an account is locked and the
|
||||
* <code>AuthenticationManager</code> can test for account locking.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* A {@link BadCredentialsException} must be thrown if incorrect
|
||||
* credentials are presented. Whilst the above exceptions are optional, an
|
||||
* <code>AuthenticationManager</code> must <B>always</B> test credentials.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Exceptions should be tested for and if applicable thrown in the order
|
||||
* expressed above (ie if an account is disabled or locked, the
|
||||
* authentication request is immediately rejected and the credentials
|
||||
* testing process is not performed). This prevents credentials being
|
||||
* tested against disabled or locked accounts.
|
||||
* </p>
|
||||
* Attempts to authenticate the passed {@link Authentication} object, returning a fully populated
|
||||
* <code>Authentication</code> object (including granted authorities) if successful.<p>An
|
||||
* <code>AuthenticationManager</code> must honour the following contract concerning exceptions:</p>
|
||||
* <p>A {@link DisabledException} must be thrown if an account is disabled and the
|
||||
* <code>AuthenticationManager</code> can test for this state.</p>
|
||||
* <p>A {@link LockedException} must be thrown if an account is locked and the
|
||||
* <code>AuthenticationManager</code> can test for account locking.</p>
|
||||
* <p>A {@link BadCredentialsException} must be thrown if incorrect credentials are presented. Whilst the
|
||||
* above exceptions are optional, an <code>AuthenticationManager</code> must <B>always</B> test credentials.</p>
|
||||
* <p>Exceptions should be tested for and if applicable thrown in the order expressed above (ie if an
|
||||
* account is disabled or locked, the authentication request is immediately rejected and the credentials testing
|
||||
* process is not performed). This prevents credentials being tested against disabled or locked accounts.</p>
|
||||
*
|
||||
* @param authentication the authentication request object
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,20 +16,16 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request could not be processed due to a system
|
||||
* problem.
|
||||
*
|
||||
* <p>
|
||||
* This might be thrown if a backend authentication repository is unavailable.
|
||||
* </p>
|
||||
* Thrown if an authentication request could not be processed due to a system problem.<p>This might be thrown if a
|
||||
* backend authentication repository is unavailable.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationServiceException extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AuthenticationServiceException</code> with the
|
||||
* specified message.
|
||||
*
|
||||
@@ -39,7 +35,7 @@ public class AuthenticationServiceException extends AuthenticationException {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AuthenticationServiceException</code> with the
|
||||
* specified message and root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,45 +22,35 @@ package org.acegisecurity;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AuthenticationTrustResolver {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Indicates whether the passed <code>Authentication</code> token
|
||||
* represents an anonymous user. Typically the framework will call this
|
||||
* method if it is trying to decide whether an
|
||||
* <code>AccessDeniedException</code> should result in a final rejection
|
||||
* (ie as would be the case if the principal was non-anonymous/fully
|
||||
* authenticated) or direct the principal to attempt actual authentication
|
||||
* (ie as would be the case if the <code>Authentication</code> was merely
|
||||
* anonymous).
|
||||
* Indicates whether the passed <code>Authentication</code> token represents an anonymous user. Typically
|
||||
* the framework will call this method if it is trying to decide whether an <code>AccessDeniedException</code>
|
||||
* should result in a final rejection (ie as would be the case if the principal was non-anonymous/fully
|
||||
* authenticated) or direct the principal to attempt actual authentication (ie as would be the case if the
|
||||
* <code>Authentication</code> was merely anonymous).
|
||||
*
|
||||
* @param authentication to test (may be <code>null</code> in which case
|
||||
* the method will always return <code>false</code>)
|
||||
* @param authentication to test (may be <code>null</code> in which case the method will always return
|
||||
* <code>false</code>)
|
||||
*
|
||||
* @return <code>true</code> the passed authentication token represented an
|
||||
* anonymous principal, <code>false</code> otherwise
|
||||
* @return <code>true</code> the passed authentication token represented an anonymous principal, <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
public boolean isAnonymous(Authentication authentication);
|
||||
|
||||
/**
|
||||
* Indicates whether the passed <code>Authentication</code> token
|
||||
* represents user that has been remembered (ie not a user that has been
|
||||
* fully authenticated).
|
||||
*
|
||||
* <p>
|
||||
* <b>No part of the framework uses this method</b>, as it is a weak
|
||||
* definition of trust levels. The method is provided simply to assist
|
||||
* with custom <code>AccessDecisionVoter</code>s and the like that you
|
||||
* might develop. Of course, you don't need to use this method either and
|
||||
* can develop your own "trust level" hierarchy instead.
|
||||
* </p>
|
||||
* Indicates whether the passed <code>Authentication</code> token represents user that has been remembered
|
||||
* (ie not a user that has been fully authenticated).<p><b>No part of the framework uses this method</b>,
|
||||
* as it is a weak definition of trust levels. The method is provided simply to assist with custom
|
||||
* <code>AccessDecisionVoter</code>s and the like that you might develop. Of course, you don't need to use this
|
||||
* method either and can develop your own "trust level" hierarchy instead.</p>
|
||||
*
|
||||
* @param authentication to test (may be <code>null</code> in which case
|
||||
* the method will always return <code>false</code>)
|
||||
* @param authentication to test (may be <code>null</code> in which case the method will always return
|
||||
* <code>false</code>)
|
||||
*
|
||||
* @return <code>true</code> the passed authentication token represented a
|
||||
* principal authenticated using a remember-me token,
|
||||
* <code>false</code> otherwise
|
||||
* @return <code>true</code> the passed authentication token represented a principal authenticated using a
|
||||
* remember-me token, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isRememberMe(Authentication authentication);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,29 +20,29 @@ import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken;
|
||||
|
||||
|
||||
/**
|
||||
* Basic implementation of {@link AuthenticationTrustResolver}.
|
||||
*
|
||||
* <p>
|
||||
* Makes trust decisions based on whether the passed
|
||||
* <code>Authentication</code> is an instance of a defined class.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If {@link #anonymousClass} or {@link #rememberMeClass} is <code>null</code>,
|
||||
* the corresponding method will always return <code>false</code>.
|
||||
* </p>
|
||||
* Basic implementation of {@link AuthenticationTrustResolver}.<p>Makes trust decisions based on whether the passed
|
||||
* <code>Authentication</code> is an instance of a defined class.</p>
|
||||
* <p>If {@link #anonymousClass} or {@link #rememberMeClass} is <code>null</code>, the corresponding method will
|
||||
* always return <code>false</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationTrustResolverImpl
|
||||
implements AuthenticationTrustResolver {
|
||||
//~ Instance fields ========================================================
|
||||
public class AuthenticationTrustResolverImpl implements AuthenticationTrustResolver {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Class anonymousClass = AnonymousAuthenticationToken.class;
|
||||
private Class rememberMeClass = RememberMeAuthenticationToken.class;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Class getAnonymousClass() {
|
||||
return anonymousClass;
|
||||
}
|
||||
|
||||
public Class getRememberMeClass() {
|
||||
return rememberMeClass;
|
||||
}
|
||||
|
||||
public boolean isAnonymous(Authentication authentication) {
|
||||
if ((anonymousClass == null) || (authentication == null)) {
|
||||
@@ -52,14 +52,6 @@ public class AuthenticationTrustResolverImpl
|
||||
return anonymousClass.isAssignableFrom(authentication.getClass());
|
||||
}
|
||||
|
||||
public void setAnonymousClass(Class anonymousClass) {
|
||||
this.anonymousClass = anonymousClass;
|
||||
}
|
||||
|
||||
public Class getAnonymousClass() {
|
||||
return anonymousClass;
|
||||
}
|
||||
|
||||
public boolean isRememberMe(Authentication authentication) {
|
||||
if ((rememberMeClass == null) || (authentication == null)) {
|
||||
return false;
|
||||
@@ -68,11 +60,11 @@ public class AuthenticationTrustResolverImpl
|
||||
return rememberMeClass.isAssignableFrom(authentication.getClass());
|
||||
}
|
||||
|
||||
public void setAnonymousClass(Class anonymousClass) {
|
||||
this.anonymousClass = anonymousClass;
|
||||
}
|
||||
|
||||
public void setRememberMeClass(Class rememberMeClass) {
|
||||
this.rememberMeClass = rememberMeClass;
|
||||
}
|
||||
|
||||
public Class getRememberMeClass() {
|
||||
return rememberMeClass;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,21 +16,16 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authorization request could not be processed due to a system
|
||||
* problem.
|
||||
*
|
||||
* <p>
|
||||
* This might be thrown if an <code>AccessDecisionManager</code> implementation
|
||||
* could not locate a required method argument, for example.
|
||||
* </p>
|
||||
* Thrown if an authorization request could not be processed due to a system problem.<p>This might be thrown if an
|
||||
* <code>AccessDecisionManager</code> implementation could not locate a required method argument, for example.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthorizationServiceException extends AccessDeniedException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AuthorizationServiceException</code> with the
|
||||
* specified message.
|
||||
*
|
||||
@@ -40,7 +35,7 @@ public class AuthorizationServiceException extends AccessDeniedException {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>AuthorizationServiceException</code> with the
|
||||
* specified message and root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,21 +16,20 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because the credentials are
|
||||
* invalid. For this exception to be thrown, it means the account is neither
|
||||
* locked nor disabled.
|
||||
* Thrown if an authentication request is rejected because the credentials are invalid. For this exception to be
|
||||
* thrown, it means the account is neither locked nor disabled.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BadCredentialsException extends AuthenticationException {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Object extraInformation;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>BadCredentialsException</code> with the specified
|
||||
* message.
|
||||
*
|
||||
@@ -45,7 +44,7 @@ public class BadCredentialsException extends AuthenticationException {
|
||||
this.extraInformation = extraInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>BadCredentialsException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
@@ -56,11 +55,10 @@ public class BadCredentialsException extends AuthenticationException {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Any additional information about the exception. Generally a
|
||||
* <code>UserDetails</code> object.
|
||||
* Any additional information about the exception. Generally a <code>UserDetails</code> object.
|
||||
*
|
||||
* @return extra information or <code>null</code>
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,28 +38,19 @@ import java.io.Serializable;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface ConfigAttribute extends Serializable {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* If the <code>ConfigAttribute</code> can be represented as a
|
||||
* <code>String</code> and that <code>String</code> is sufficient in
|
||||
* precision to be relied upon as a configuration parameter by a {@link
|
||||
* RunAsManager}, {@link AccessDecisionManager} or
|
||||
* <code>AccessDecisionManager</code> delegate, this method should return
|
||||
* such a <code>String</code>.
|
||||
*
|
||||
* <p>
|
||||
* If the <code>ConfigAttribute</code> cannot be expressed with sufficient
|
||||
* precision as a <code>String</code>, <code>null</code> should be
|
||||
* returned. Returning <code>null</code> will require any relying classes
|
||||
* to specifically support the <code>ConfigAttribute</code>
|
||||
* implementation, so returning <code>null</code> should be avoided
|
||||
* unless actually required.
|
||||
* </p>
|
||||
* If the <code>ConfigAttribute</code> can be represented as a <code>String</code> and that
|
||||
* <code>String</code> is sufficient in precision to be relied upon as a configuration parameter by a {@link
|
||||
* RunAsManager}, {@link AccessDecisionManager} or <code>AccessDecisionManager</code> delegate, this method should
|
||||
* return such a <code>String</code>.<p>If the <code>ConfigAttribute</code> cannot be expressed with
|
||||
* sufficient precision as a <code>String</code>, <code>null</code> should be returned. Returning
|
||||
* <code>null</code> will require any relying classes to specifically support the <code>ConfigAttribute</code>
|
||||
* implementation, so returning <code>null</code> should be avoided unless actually required.</p>
|
||||
*
|
||||
* @return a representation of the configuration attribute (or
|
||||
* <code>null</code> if the configuration attribute cannot be
|
||||
* expressed as a <code>String</code> with sufficient precision).
|
||||
* @return a representation of the configuration attribute (or <code>null</code> if the configuration attribute
|
||||
* cannot be expressed as a <code>String</code> with sufficient precision).
|
||||
*/
|
||||
public String getAttribute();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,52 +23,29 @@ import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* Holds a group of {@link ConfigAttribute}s that are associated with a given
|
||||
* secure object target.
|
||||
*
|
||||
* <p>
|
||||
* All the <code>ConfigAttributeDefinition</code>s associated with a given
|
||||
* {@link org.acegisecurity.intercept.AbstractSecurityInterceptor} are
|
||||
* stored in an {@link org.acegisecurity.intercept.ObjectDefinitionSource}.
|
||||
* </p>
|
||||
* Holds a group of {@link ConfigAttribute}s that are associated with a given secure object target.<p>All the
|
||||
* <code>ConfigAttributeDefinition</code>s associated with a given {@link
|
||||
* org.acegisecurity.intercept.AbstractSecurityInterceptor} are stored in an {@link
|
||||
* org.acegisecurity.intercept.ObjectDefinitionSource}.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ConfigAttributeDefinition implements Serializable {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private List configAttributes = new Vector();
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public ConfigAttributeDefinition() {
|
||||
super();
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Returns an <code>Iterator</code> over all the
|
||||
* <code>ConfigAttribute</code>s defined by this
|
||||
* <code>ConfigAttributeDefinition</code>.
|
||||
*
|
||||
* <P>
|
||||
* Allows <code>AccessDecisionManager</code>s and other classes to loop
|
||||
* through every configuration attribute associated with a target secure
|
||||
* object.
|
||||
* </p>
|
||||
*
|
||||
* @return all the configuration attributes stored by the instance, or
|
||||
* <code>null</code> if an <code>Iterator</code> is unavailable
|
||||
*/
|
||||
public Iterator getConfigAttributes() {
|
||||
return this.configAttributes.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a <code>ConfigAttribute</code> that is related to the secure object
|
||||
* method.
|
||||
* Adds a <code>ConfigAttribute</code> that is related to the secure object method.
|
||||
*
|
||||
* @param newConfigAttribute the new configuration attribute to add
|
||||
*/
|
||||
@@ -77,13 +54,13 @@ public class ConfigAttributeDefinition implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the specified <code>ConfigAttribute</code> is
|
||||
* contained within this <code>ConfigAttributeDefinition</code>.
|
||||
* Indicates whether the specified <code>ConfigAttribute</code> is contained within this
|
||||
* <code>ConfigAttributeDefinition</code>.
|
||||
*
|
||||
* @param configAttribute the attribute to locate
|
||||
*
|
||||
* @return <code>true</code> if the specified <code>ConfigAttribute</code>
|
||||
* is contained, <code>false</code> otherwise
|
||||
* @return <code>true</code> if the specified <code>ConfigAttribute</code> is contained, <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
public boolean contains(ConfigAttribute configAttribute) {
|
||||
return configAttributes.contains(configAttribute);
|
||||
@@ -117,6 +94,18 @@ public class ConfigAttributeDefinition implements Serializable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Iterator</code> over all the <code>ConfigAttribute</code>s defined by this
|
||||
* <code>ConfigAttributeDefinition</code>.<P>Allows <code>AccessDecisionManager</code>s and other classes
|
||||
* to loop through every configuration attribute associated with a target secure object.</p>
|
||||
*
|
||||
* @return all the configuration attributes stored by the instance, or <code>null</code> if an
|
||||
* <code>Iterator</code> is unavailable
|
||||
*/
|
||||
public Iterator getConfigAttributes() {
|
||||
return this.configAttributes.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of <code>ConfigAttribute</code>s defined by this
|
||||
* <code>ConfigAttributeDefinition</code>.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,19 +21,15 @@ import java.beans.PropertyEditorSupport;
|
||||
|
||||
|
||||
/**
|
||||
* A property editor that can create a populated {@link
|
||||
* ConfigAttributeDefinition} from a comma separated list of values.
|
||||
*
|
||||
* <P>
|
||||
* Trims preceding and trailing spaces from presented command separated tokens,
|
||||
* as this can be a source of hard-to-spot configuration issues for end users.
|
||||
* </p>
|
||||
* A property editor that can create a populated {@link ConfigAttributeDefinition} from a comma separated list of
|
||||
* values.<P>Trims preceding and trailing spaces from presented command separated tokens, as this can be a source
|
||||
* of hard-to-spot configuration issues for end users.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ConfigAttributeEditor extends PropertyEditorSupport {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void setAsText(String s) throws IllegalArgumentException {
|
||||
if ((s == null) || "".equals(s)) {
|
||||
@@ -43,8 +39,7 @@ public class ConfigAttributeEditor extends PropertyEditorSupport {
|
||||
ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition();
|
||||
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
configDefinition.addConfigAttribute(new SecurityConfig(
|
||||
tokens[i].trim()));
|
||||
configDefinition.addConfigAttribute(new SecurityConfig(tokens[i].trim()));
|
||||
}
|
||||
|
||||
setValue(configDefinition);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,17 +16,16 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because the account's
|
||||
* credentials have expired. Makes no assertion as to whether or not the
|
||||
* credentials were valid.
|
||||
* Thrown if an authentication request is rejected because the account's credentials have expired. Makes no
|
||||
* assertion as to whether or not the credentials were valid.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CredentialsExpiredException extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>CredentialsExpiredException</code> with the specified
|
||||
* message.
|
||||
*
|
||||
@@ -36,7 +35,7 @@ public class CredentialsExpiredException extends AuthenticationException {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>CredentialsExpiredException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,17 +16,16 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because the account is
|
||||
* disabled. Makes no assertion as to whether or not the credentials were
|
||||
* valid.
|
||||
* Thrown if an authentication request is rejected because the account is disabled. Makes no assertion as to
|
||||
* whether or not the credentials were valid.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class DisabledException extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>DisabledException</code> with the specified message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
@@ -35,7 +34,7 @@ public class DisabledException extends AuthenticationException {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>DisabledException</code> with the specified message
|
||||
* and root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,27 +28,19 @@ package org.acegisecurity;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface GrantedAuthority {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* If the <code>GrantedAuthority</code> can be represented as a
|
||||
* <code>String</code> and that <code>String</code> is sufficient in
|
||||
* precision to be relied upon for an access control decision by an {@link
|
||||
* AccessDecisionManager} (or delegate), this method should return such a
|
||||
* <code>String</code>.
|
||||
*
|
||||
* <p>
|
||||
* If the <code>GrantedAuthority</code> cannot be expressed with sufficient
|
||||
* precision as a <code>String</code>, <code>null</code> should be
|
||||
* returned. Returning <code>null</code> will require an
|
||||
* <code>AccessDecisionManager</code> (or delegate) to specifically
|
||||
* support the <code>GrantedAuthority</code> implementation, so returning
|
||||
* <code>null</code> should be avoided unless actually required.
|
||||
* </p>
|
||||
* If the <code>GrantedAuthority</code> can be represented as a <code>String</code> and that
|
||||
* <code>String</code> is sufficient in precision to be relied upon for an access control decision by an {@link
|
||||
* AccessDecisionManager} (or delegate), this method should return such a <code>String</code>.<p>If the
|
||||
* <code>GrantedAuthority</code> cannot be expressed with sufficient precision as a <code>String</code>,
|
||||
* <code>null</code> should be returned. Returning <code>null</code> will require an
|
||||
* <code>AccessDecisionManager</code> (or delegate) to specifically support the <code>GrantedAuthority</code>
|
||||
* implementation, so returning <code>null</code> should be avoided unless actually required.</p>
|
||||
*
|
||||
* @return a representation of the granted authority (or <code>null</code>
|
||||
* if the granted authority cannot be expressed as a
|
||||
* <code>String</code> with sufficient precision).
|
||||
* @return a representation of the granted authority (or <code>null</code> if the granted authority cannot be
|
||||
* expressed as a <code>String</code> with sufficient precision).
|
||||
*/
|
||||
public String getAuthority();
|
||||
}
|
||||
|
||||
@@ -19,29 +19,25 @@ import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Basic concrete implementation of a {@link GrantedAuthority}.
|
||||
*
|
||||
* <p>
|
||||
* Stores a <code>String</code> representation of an authority granted to the
|
||||
* {@link Authentication} object.
|
||||
* </p>
|
||||
* Basic concrete implementation of a {@link GrantedAuthority}.<p>Stores a <code>String</code> representation of an
|
||||
* authority granted to the {@link Authentication} object.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class GrantedAuthorityImpl implements GrantedAuthority, Serializable {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private String role;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public GrantedAuthorityImpl(String role) {
|
||||
super();
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof String) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,26 +16,19 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because the credentials are
|
||||
* not sufficiently trusted.
|
||||
*
|
||||
* <p>
|
||||
* {@link org.acegisecurity.vote.AccessDecisionVoter}s will typically throw
|
||||
* this exception if they are dissatisfied with the level of the
|
||||
* authentication, such as if performed using a remember-me mechanism or
|
||||
* anonymously. The commonly used {@link
|
||||
* org.acegisecurity.ui.ExceptionTranslationFilter} will thus
|
||||
* cause the <code>AuthenticationEntryPoint</code> to be called, allowing the
|
||||
* principal to authenticate with a stronger level of authentication.
|
||||
* </p>
|
||||
* Thrown if an authentication request is rejected because the credentials are not sufficiently trusted.<p>{{@link
|
||||
* org.acegisecurity.vote.AccessDecisionVoter}s will typically throw this exception if they are dissatisfied with the
|
||||
* level of the authentication, such as if performed using a remember-me mechanism or anonymously. The commonly used
|
||||
* {@link org.acegisecurity.ui.ExceptionTranslationFilter} will thus cause the <code>AuthenticationEntryPoint</code>
|
||||
* to be called, allowing the principal to authenticate with a stronger level of authentication.}</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class InsufficientAuthenticationException extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>InsufficientAuthenticationException</code> with the
|
||||
* specified message.
|
||||
*
|
||||
@@ -45,7 +38,7 @@ public class InsufficientAuthenticationException extends AuthenticationException
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an <code>InsufficientAuthenticationException</code> with the
|
||||
* specified message and root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,16 +16,16 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because the account is
|
||||
* locked. Makes no assertion as to whether or not the credentials were valid.
|
||||
* Thrown if an authentication request is rejected because the account is locked. Makes no assertion as to whether
|
||||
* or not the credentials were valid.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class LockedException extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>LockedException</code> with the specified message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
@@ -34,7 +34,7 @@ public class LockedException extends AuthenticationException {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>LockedException</code> with the specified message and
|
||||
* root cause.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,19 +16,18 @@
|
||||
package org.acegisecurity;
|
||||
|
||||
/**
|
||||
* Simply accepts as valid whatever is passed to it, if
|
||||
* <code>grantAccess</code> is set to <code>true</code>.
|
||||
* Simply accepts as valid whatever is passed to it, if <code>grantAccess</code> is set to <code>true</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Wesley Hall
|
||||
* @version $Id$
|
||||
*/
|
||||
public class MockAuthenticationManager extends AbstractAuthenticationManager {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private boolean grantAccess = true;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public MockAuthenticationManager(boolean grantAccess) {
|
||||
this.grantAccess = grantAccess;
|
||||
@@ -38,15 +37,14 @@ public class MockAuthenticationManager extends AbstractAuthenticationManager {
|
||||
super();
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Authentication doAuthentication(Authentication authentication)
|
||||
throws AuthenticationException {
|
||||
if (grantAccess) {
|
||||
return authentication;
|
||||
} else {
|
||||
throw new BadCredentialsException(
|
||||
"MockAuthenticationManager instructed to deny access");
|
||||
throw new BadCredentialsException("MockAuthenticationManager instructed to deny access");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -58,47 +58,37 @@ package org.acegisecurity;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface RunAsManager {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Returns a replacement <code>Authentication</code> object for the current
|
||||
* secure object invocation, or <code>null</code> if replacement not
|
||||
* required.
|
||||
* Returns a replacement <code>Authentication</code> object for the current secure object invocation, or
|
||||
* <code>null</code> if replacement not required.
|
||||
*
|
||||
* @param authentication the caller invoking the secure object
|
||||
* @param object the secured object being called
|
||||
* @param config the configuration attributes associated with the secure
|
||||
* object being invoked
|
||||
* @param config the configuration attributes associated with the secure object being invoked
|
||||
*
|
||||
* @return a replacement object to be used for duration of the secure
|
||||
* object invocation, or <code>null</code> if the
|
||||
* <code>Authentication</code> should be left as is
|
||||
* @return a replacement object to be used for duration of the secure object invocation, or <code>null</code> if
|
||||
* the <code>Authentication</code> should be left as is
|
||||
*/
|
||||
public Authentication buildRunAs(Authentication authentication,
|
||||
Object object, ConfigAttributeDefinition config);
|
||||
public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config);
|
||||
|
||||
/**
|
||||
* Indicates whether this <code>RunAsManager</code> is able to process the
|
||||
* passed <code>ConfigAttribute</code>.
|
||||
*
|
||||
* <p>
|
||||
* This allows the <code>AbstractSecurityInterceptor</code> to check every
|
||||
* configuration attribute can be consumed by the configured
|
||||
* <code>AccessDecisionManager</code> and/or <code>RunAsManager</code>
|
||||
* and/or <code>AfterInvocationManager</code>.
|
||||
* </p>
|
||||
* Indicates whether this <code>RunAsManager</code> is able to process the passed
|
||||
* <code>ConfigAttribute</code>.<p>This allows the <code>AbstractSecurityInterceptor</code> to check every
|
||||
* configuration attribute can be consumed by the configured <code>AccessDecisionManager</code> and/or
|
||||
* <code>RunAsManager</code> and/or <code>AfterInvocationManager</code>.</p>
|
||||
*
|
||||
* @param attribute a configuration attribute that has been configured
|
||||
* against the <code>AbstractSecurityInterceptor</code>
|
||||
* @param attribute a configuration attribute that has been configured against the
|
||||
* <code>AbstractSecurityInterceptor</code>
|
||||
*
|
||||
* @return <code>true</code> if this <code>RunAsManager</code> can support
|
||||
* the passed configuration attribute
|
||||
* @return <code>true</code> if this <code>RunAsManager</code> can support the passed configuration attribute
|
||||
*/
|
||||
public boolean supports(ConfigAttribute attribute);
|
||||
|
||||
/**
|
||||
* Indicates whether the <code>RunAsManager</code> implementation is able
|
||||
* to provide run-as replacement for the indicated secure object type.
|
||||
* Indicates whether the <code>RunAsManager</code> implementation is able to provide run-as replacement for
|
||||
* the indicated secure object type.
|
||||
*
|
||||
* @param clazz the class that is being queried
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,21 +22,17 @@ package org.acegisecurity;
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SecurityConfig implements ConfigAttribute {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private String attrib;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public SecurityConfig(String config) {
|
||||
this.attrib = config;
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public String getAttribute() {
|
||||
return this.attrib;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof String) {
|
||||
@@ -52,6 +48,10 @@ public class SecurityConfig implements ConfigAttribute {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getAttribute() {
|
||||
return this.attrib;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.attrib.hashCode();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@ package org.acegisecurity.acl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Marker interface representing an access control list entry associated with a
|
||||
* specific domain object instance.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,33 +26,26 @@ import org.acegisecurity.Authentication;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AclManager {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Obtains the ACLs that apply to the specified domain instance.
|
||||
*
|
||||
* @param domainInstance the instance for which ACL information is required
|
||||
* (never <code>null</code>)
|
||||
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
|
||||
*
|
||||
* @return the ACLs that apply, or <code>null</code> if no ACLs apply to
|
||||
* the specified domain instance
|
||||
* @return the ACLs that apply, or <code>null</code> if no ACLs apply to the specified domain instance
|
||||
*/
|
||||
public AclEntry[] getAcls(Object domainInstance);
|
||||
|
||||
/**
|
||||
* Obtains the ACLs that apply to the specified domain instance, but only
|
||||
* including those ACLs which have been granted to the presented
|
||||
* <code>Authentication</code> object
|
||||
* Obtains the ACLs that apply to the specified domain instance, but only including those ACLs which have
|
||||
* been granted to the presented <code>Authentication</code> object
|
||||
*
|
||||
* @param domainInstance the instance for which ACL information is required
|
||||
* (never <code>null</code>)
|
||||
* @param authentication the prncipal for which ACL information should be
|
||||
* filtered (never <code>null</code>)
|
||||
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
|
||||
* @param authentication the prncipal for which ACL information should be filtered (never <code>null</code>)
|
||||
*
|
||||
* @return only those ACLs applying to the domain instance that have been
|
||||
* granted to the principal (or <code>null</code>) if no such ACLs
|
||||
* are found
|
||||
* @return only those ACLs applying to the domain instance that have been granted to the principal (or
|
||||
* <code>null</code>) if no such ACLs are found
|
||||
*/
|
||||
public AclEntry[] getAcls(Object domainInstance,
|
||||
Authentication authentication);
|
||||
public AclEntry[] getAcls(Object domainInstance, Authentication authentication);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@ package org.acegisecurity.acl;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates a class can process a given domain object instance and
|
||||
* authoritatively return the ACLs that apply.
|
||||
@@ -29,54 +30,38 @@ import org.acegisecurity.Authentication;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AclProvider {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Obtains the ACLs that apply to the specified domain instance.
|
||||
*
|
||||
* <P>
|
||||
* Will never be called unless the {@link #supports(Object)} method
|
||||
* returned <code>true</code>.
|
||||
* </p>
|
||||
* Obtains the ACLs that apply to the specified domain instance.<P>Will never be called unless the {@link
|
||||
* #supports(Object)} method returned <code>true</code>.</p>
|
||||
*
|
||||
* @param domainInstance the instance for which ACL information is required
|
||||
* (never <code>null</code>)
|
||||
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
|
||||
*
|
||||
* @return the ACLs that apply, or <code>null</code> if no ACLs apply to
|
||||
* the specified domain instance
|
||||
* @return the ACLs that apply, or <code>null</code> if no ACLs apply to the specified domain instance
|
||||
*/
|
||||
public AclEntry[] getAcls(Object domainInstance);
|
||||
|
||||
/**
|
||||
* Obtains the ACLs that apply to the specified domain instance
|
||||
* and presented <code>Authentication</code> object.
|
||||
* Obtains the ACLs that apply to the specified domain instance and presented <code>Authentication</code>
|
||||
* object.<P>Will never be called unless the {@link #supports(Object)} method returned <code>true</code>.</p>
|
||||
*
|
||||
* <P>
|
||||
* Will never be called unless the {@link #supports(Object)} method
|
||||
* returned <code>true</code>.
|
||||
* </p>
|
||||
*
|
||||
* @param domainInstance the instance for which ACL information is required
|
||||
* (never <code>null</code>)
|
||||
* @param authentication the prncipal for which ACL information should be
|
||||
* filtered (never <code>null</code>)
|
||||
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
|
||||
* @param authentication the prncipal for which ACL information should be filtered (never <code>null</code>)
|
||||
*
|
||||
* @return only those ACLs applying to the domain instance that have been
|
||||
* granted to the principal (or <code>null</code>) if no such ACLs
|
||||
* are found
|
||||
* @return only those ACLs applying to the domain instance that have been granted to the principal (or
|
||||
* <code>null</code>) if no such ACLs are found
|
||||
*/
|
||||
public AclEntry[] getAcls(Object domainInstance,
|
||||
Authentication authentication);
|
||||
public AclEntry[] getAcls(Object domainInstance, Authentication authentication);
|
||||
|
||||
/**
|
||||
* Indicates whether this <code>AclProvider</code> can authoritatively
|
||||
* return ACL information for the specified domain object instance.
|
||||
* Indicates whether this <code>AclProvider</code> can authoritatively return ACL information for the
|
||||
* specified domain object instance.
|
||||
*
|
||||
* @param domainInstance the instance for which ACL information is required
|
||||
* (never <code>null</code>)
|
||||
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
|
||||
*
|
||||
* @return <code>true</code> if this provider is authoritative for the
|
||||
* specified domain object instance, <code>false</code> otherwise
|
||||
* @return <code>true</code> if this provider is authoritative for the specified domain object instance,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean supports(Object domainInstance);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Iterator;
|
||||
@@ -28,27 +29,31 @@ import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Iterates through a list of {@link AclProvider}s to locate the ACLs that
|
||||
* apply to a given domain object instance.
|
||||
*
|
||||
* <P>
|
||||
* If no compatible provider is found, it is assumed that no ACLs apply for the
|
||||
* specified domain object instance and <code>null</code> is returned.
|
||||
* </p>
|
||||
* Iterates through a list of {@link AclProvider}s to locate the ACLs that apply to a given domain object instance.<P>If
|
||||
* no compatible provider is found, it is assumed that no ACLs apply for the specified domain object instance and
|
||||
* <code>null</code> is returned.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclProviderManager implements AclManager, InitializingBean {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AclProviderManager.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private List providers;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
checkIfValidList(this.providers);
|
||||
}
|
||||
|
||||
private void checkIfValidList(List listToCheck) {
|
||||
Assert.notEmpty(listToCheck, "A list of AclManagers is required");
|
||||
}
|
||||
|
||||
public AclEntry[] getAcls(Object domainInstance) {
|
||||
Assert.notNull(domainInstance, "domainInstance is null - violating interface contract");
|
||||
@@ -60,8 +65,7 @@ public class AclProviderManager implements AclManager, InitializingBean {
|
||||
|
||||
if (provider.supports(domainInstance)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ACL lookup using "
|
||||
+ provider.getClass().getName());
|
||||
logger.debug("ACL lookup using " + provider.getClass().getName());
|
||||
}
|
||||
|
||||
return provider.getAcls(domainInstance);
|
||||
@@ -69,15 +73,13 @@ public class AclProviderManager implements AclManager, InitializingBean {
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No AclProvider found for "
|
||||
+ domainInstance.toString());
|
||||
logger.debug("No AclProvider found for " + domainInstance.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public AclEntry[] getAcls(Object domainInstance,
|
||||
Authentication authentication) {
|
||||
public AclEntry[] getAcls(Object domainInstance, Authentication authentication) {
|
||||
Assert.notNull(domainInstance, "domainInstance is null - violating interface contract");
|
||||
Assert.notNull(authentication, "authentication is null - violating interface contract");
|
||||
|
||||
@@ -88,34 +90,34 @@ public class AclProviderManager implements AclManager, InitializingBean {
|
||||
|
||||
if (provider.supports(domainInstance)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ACL lookup using "
|
||||
+ provider.getClass().getName());
|
||||
logger.debug("ACL lookup using " + provider.getClass().getName());
|
||||
}
|
||||
|
||||
return provider.getAcls(domainInstance, authentication);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Provider " + provider.toString()
|
||||
+ " does not support " + domainInstance);
|
||||
logger.debug("Provider " + provider.toString() + " does not support " + domainInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No AclProvider found for "
|
||||
+ domainInstance.toString());
|
||||
logger.debug("No AclProvider found for " + domainInstance.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List getProviders() {
|
||||
return this.providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link AclProvider} objects to be used for ACL determinations.
|
||||
*
|
||||
* @param newList that should be used for ACL determinations
|
||||
*
|
||||
* @throws IllegalArgumentException if an invalid provider was included in
|
||||
* the list
|
||||
* @throws IllegalArgumentException if an invalid provider was included in the list
|
||||
*/
|
||||
public void setProviders(List newList) {
|
||||
checkIfValidList(newList);
|
||||
@@ -130,24 +132,11 @@ public class AclProviderManager implements AclManager, InitializingBean {
|
||||
|
||||
AclProvider attemptToCast = (AclProvider) currentObject;
|
||||
} catch (ClassCastException cce) {
|
||||
throw new IllegalArgumentException("AclProvider "
|
||||
+ currentObject.getClass().getName()
|
||||
throw new IllegalArgumentException("AclProvider " + currentObject.getClass().getName()
|
||||
+ " must implement AclProvider");
|
||||
}
|
||||
}
|
||||
|
||||
this.providers = newList;
|
||||
}
|
||||
|
||||
public List getProviders() {
|
||||
return this.providers;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
checkIfValidList(this.providers);
|
||||
}
|
||||
|
||||
private void checkIfValidList(List listToCheck) {
|
||||
Assert.notEmpty(listToCheck, "A list of AclManagers is required");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,27 +17,24 @@ package org.acegisecurity.acl.basic;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract implementation of {@link BasicAclEntry}.
|
||||
*
|
||||
* <P>
|
||||
* Provides core bit mask handling methods.
|
||||
* </p>
|
||||
* Abstract implementation of {@link BasicAclEntry}.<P>Provides core bit mask handling methods.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractBasicAclEntry implements BasicAclEntry {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AbstractBasicAclEntry.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AclObjectIdentity aclObjectIdentity;
|
||||
private AclObjectIdentity aclObjectParentIdentity;
|
||||
@@ -45,10 +42,9 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry {
|
||||
private int[] validPermissions;
|
||||
private int mask = 0; // default means no permissions
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AbstractBasicAclEntry(Object recipient,
|
||||
AclObjectIdentity aclObjectIdentity,
|
||||
public AbstractBasicAclEntry(Object recipient, AclObjectIdentity aclObjectIdentity,
|
||||
AclObjectIdentity aclObjectParentIdentity, int mask) {
|
||||
Assert.notNull(recipient, "recipient cannot be null");
|
||||
|
||||
@@ -59,10 +55,8 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry {
|
||||
|
||||
for (int i = 0; i < validPermissions.length; i++) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Valid permission: "
|
||||
+ printPermissionsBlock(validPermissions[i]) + " "
|
||||
+ printBinary(validPermissions[i]) + " ("
|
||||
+ validPermissions[i] + ")");
|
||||
logger.debug("Valid permission: " + printPermissionsBlock(validPermissions[i]) + " "
|
||||
+ printBinary(validPermissions[i]) + " (" + validPermissions[i] + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +66,7 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* A protected constructor for use by Hibernate.
|
||||
*/
|
||||
protected AbstractBasicAclEntry() {
|
||||
@@ -80,86 +74,7 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry {
|
||||
Arrays.sort(validPermissions);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity) {
|
||||
this.aclObjectIdentity = aclObjectIdentity;
|
||||
}
|
||||
|
||||
public AclObjectIdentity getAclObjectIdentity() {
|
||||
return this.aclObjectIdentity;
|
||||
}
|
||||
|
||||
public void setAclObjectParentIdentity(
|
||||
AclObjectIdentity aclObjectParentIdentity) {
|
||||
this.aclObjectParentIdentity = aclObjectParentIdentity;
|
||||
}
|
||||
|
||||
public AclObjectIdentity getAclObjectParentIdentity() {
|
||||
return this.aclObjectParentIdentity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must indicate the permissions they support. Each base
|
||||
* permission should be an integer with a base 2. ie: the first permission
|
||||
* is 2^^0 (1), the second permission is 2^^1 (2), the third permission is
|
||||
* 2^^2 (4) etc. Each base permission should be exposed by the subclass as
|
||||
* a <code>public static final int</code>. It is further recommended that
|
||||
* valid combinations of permissions are also exposed as <code>public
|
||||
* static final int</code>s.
|
||||
*
|
||||
* <P>
|
||||
* This method returns all permission integers that are allowed to be used
|
||||
* together. <B>This must include any combinations of valid
|
||||
* permissions</b>. So if the permissions indicated by 2^^2 (4) and 2^^1
|
||||
* (2) can be used together, one of the integers returned by this method
|
||||
* must be 6 (4 + 2). Otherwise attempts to set the permission will be
|
||||
* rejected, as the final resulting mask will be rejected.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* Whilst it may seem unduly time onerous to return every valid permission
|
||||
* <B>combination</B>, doing so delivers maximum flexibility in ensuring
|
||||
* ACLs only reflect logical combinations. For example, it would be
|
||||
* inappropriate to grant a "read" and "write" permission along with an
|
||||
* "unrestricted" permission, as the latter implies the former
|
||||
* permissions.
|
||||
* </p>
|
||||
*
|
||||
* @return <b>every</b> valid combination of permissions
|
||||
*/
|
||||
public abstract int[] getValidPermissions();
|
||||
|
||||
/**
|
||||
* Outputs the permissions in a human-friendly format. For example, this
|
||||
* method may return "CR-D" to indicate the passed integer permits create,
|
||||
* permits read, does not permit update, and permits delete.
|
||||
*
|
||||
* @param i the integer containing the mask which should be printed
|
||||
*
|
||||
* @return the human-friend formatted block
|
||||
*/
|
||||
public abstract String printPermissionsBlock(int i);
|
||||
|
||||
public void setMask(int mask) {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
public int getMask() {
|
||||
return this.mask;
|
||||
}
|
||||
|
||||
public boolean isPermitted(int permissionToCheck) {
|
||||
return isPermitted(this.mask, permissionToCheck);
|
||||
}
|
||||
|
||||
public void setRecipient(Object recipient) {
|
||||
this.recipient = recipient;
|
||||
}
|
||||
|
||||
public Object getRecipient() {
|
||||
return this.recipient;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public int addPermission(int permissionToAdd) {
|
||||
return addPermissions(new int[] {permissionToAdd});
|
||||
@@ -167,29 +82,25 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry {
|
||||
|
||||
public int addPermissions(int[] permissionsToAdd) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask)
|
||||
+ " " + printBinary(mask) + " (" + mask + ")");
|
||||
logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " (" + mask
|
||||
+ ")");
|
||||
}
|
||||
|
||||
for (int i = 0; i < permissionsToAdd.length; i++) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Add permission: "
|
||||
+ printPermissionsBlock(permissionsToAdd[i]) + " "
|
||||
+ printBinary(permissionsToAdd[i]) + " ("
|
||||
+ permissionsToAdd[i] + ")");
|
||||
logger.debug("Add permission: " + printPermissionsBlock(permissionsToAdd[i]) + " "
|
||||
+ printBinary(permissionsToAdd[i]) + " (" + permissionsToAdd[i] + ")");
|
||||
}
|
||||
|
||||
this.mask |= permissionsToAdd[i];
|
||||
}
|
||||
|
||||
if (Arrays.binarySearch(validPermissions, this.mask) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Resulting permission set will be invalid.");
|
||||
throw new IllegalArgumentException("Resulting permission set will be invalid.");
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("AFTER Permissions: "
|
||||
+ printPermissionsBlock(mask) + " " + printBinary(mask)
|
||||
+ " (" + mask + ")");
|
||||
logger.debug("AFTER Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " ("
|
||||
+ mask + ")");
|
||||
}
|
||||
|
||||
return this.mask;
|
||||
@@ -202,65 +113,67 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry {
|
||||
|
||||
public int deletePermissions(int[] permissionsToDelete) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask)
|
||||
+ " " + printBinary(mask) + " (" + mask + ")");
|
||||
logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " (" + mask
|
||||
+ ")");
|
||||
}
|
||||
|
||||
for (int i = 0; i < permissionsToDelete.length; i++) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Delete permission: "
|
||||
+ printPermissionsBlock(permissionsToDelete[i]) + " "
|
||||
+ printBinary(permissionsToDelete[i]) + " ("
|
||||
+ permissionsToDelete[i] + ")");
|
||||
logger.debug("Delete permission: " + printPermissionsBlock(permissionsToDelete[i]) + " "
|
||||
+ printBinary(permissionsToDelete[i]) + " (" + permissionsToDelete[i] + ")");
|
||||
}
|
||||
|
||||
this.mask &= ~permissionsToDelete[i];
|
||||
}
|
||||
|
||||
if (Arrays.binarySearch(validPermissions, this.mask) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Resulting permission set will be invalid.");
|
||||
throw new IllegalArgumentException("Resulting permission set will be invalid.");
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("AFTER Permissions: "
|
||||
+ printPermissionsBlock(mask) + " " + printBinary(mask)
|
||||
+ " (" + mask + ")");
|
||||
logger.debug("AFTER Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " ("
|
||||
+ mask + ")");
|
||||
}
|
||||
|
||||
return this.mask;
|
||||
}
|
||||
}
|
||||
|
||||
public AclObjectIdentity getAclObjectIdentity() {
|
||||
return this.aclObjectIdentity;
|
||||
}
|
||||
|
||||
public AclObjectIdentity getAclObjectParentIdentity() {
|
||||
return this.aclObjectParentIdentity;
|
||||
}
|
||||
|
||||
public int getMask() {
|
||||
return this.mask;
|
||||
}
|
||||
|
||||
public Object getRecipient() {
|
||||
return this.recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the permissions in human-friendly format for the current
|
||||
* <code>AbstractBasicAclEntry</code>'s mask.
|
||||
* Subclasses must indicate the permissions they support. Each base permission should be an integer with a
|
||||
* base 2. ie: the first permission is 2^^0 (1), the second permission is 2^^1 (2), the third permission is 2^^2
|
||||
* (4) etc. Each base permission should be exposed by the subclass as a <code>public static final int</code>. It
|
||||
* is further recommended that valid combinations of permissions are also exposed as <code>public static final
|
||||
* int</code>s.<P>This method returns all permission integers that are allowed to be used together. <B>This
|
||||
* must include any combinations of valid permissions</b>. So if the permissions indicated by 2^^2 (4) and 2^^1
|
||||
* (2) can be used together, one of the integers returned by this method must be 6 (4 + 2). Otherwise attempts to
|
||||
* set the permission will be rejected, as the final resulting mask will be rejected.</p>
|
||||
* <P>Whilst it may seem unduly time onerous to return every valid permission <B>combination</B>, doing so
|
||||
* delivers maximum flexibility in ensuring ACLs only reflect logical combinations. For example, it would be
|
||||
* inappropriate to grant a "read" and "write" permission along with an "unrestricted" permission, as the latter
|
||||
* implies the former permissions.</p>
|
||||
*
|
||||
* @return the human-friendly formatted block for this instance
|
||||
* @return <b>every</b> valid combination of permissions
|
||||
*/
|
||||
public String printPermissionsBlock() {
|
||||
return printPermissionsBlock(this.mask);
|
||||
}
|
||||
public abstract int[] getValidPermissions();
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(getClass().getName());
|
||||
sb.append("[").append(aclObjectIdentity).append(",").append(recipient);
|
||||
sb.append("=").append(printPermissionsBlock(mask)).append(" ");
|
||||
sb.append(printBinary(mask)).append(" (");
|
||||
sb.append(mask).append(")").append("]");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int togglePermission(int permissionToToggle) {
|
||||
this.mask ^= permissionToToggle;
|
||||
|
||||
if (Arrays.binarySearch(validPermissions, this.mask) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Resulting permission set will be invalid.");
|
||||
} else {
|
||||
return this.mask;
|
||||
}
|
||||
public boolean isPermitted(int permissionToCheck) {
|
||||
return isPermitted(this.mask, permissionToCheck);
|
||||
}
|
||||
|
||||
protected boolean isPermitted(int maskToCheck, int permissionToCheck) {
|
||||
@@ -278,4 +191,61 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry {
|
||||
|
||||
return temp2.replace('0', '.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the permissions in a human-friendly format. For example, this method may return "CR-D" to
|
||||
* indicate the passed integer permits create, permits read, does not permit update, and permits delete.
|
||||
*
|
||||
* @param i the integer containing the mask which should be printed
|
||||
*
|
||||
* @return the human-friend formatted block
|
||||
*/
|
||||
public abstract String printPermissionsBlock(int i);
|
||||
|
||||
/**
|
||||
* Outputs the permissions in human-friendly format for the current <code>AbstractBasicAclEntry</code>'s
|
||||
* mask.
|
||||
*
|
||||
* @return the human-friendly formatted block for this instance
|
||||
*/
|
||||
public String printPermissionsBlock() {
|
||||
return printPermissionsBlock(this.mask);
|
||||
}
|
||||
|
||||
public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity) {
|
||||
this.aclObjectIdentity = aclObjectIdentity;
|
||||
}
|
||||
|
||||
public void setAclObjectParentIdentity(AclObjectIdentity aclObjectParentIdentity) {
|
||||
this.aclObjectParentIdentity = aclObjectParentIdentity;
|
||||
}
|
||||
|
||||
public void setMask(int mask) {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
public void setRecipient(Object recipient) {
|
||||
this.recipient = recipient;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(getClass().getName());
|
||||
sb.append("[").append(aclObjectIdentity).append(",").append(recipient);
|
||||
sb.append("=").append(printPermissionsBlock(mask)).append(" ");
|
||||
sb.append(printBinary(mask)).append(" (");
|
||||
sb.append(mask).append(")").append("]");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int togglePermission(int permissionToToggle) {
|
||||
this.mask ^= permissionToToggle;
|
||||
|
||||
if (Arrays.binarySearch(validPermissions, this.mask) < 0) {
|
||||
throw new IllegalArgumentException("Resulting permission set will be invalid.");
|
||||
} else {
|
||||
return this.mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,22 +44,19 @@ import java.io.Serializable;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AclObjectIdentity extends Serializable {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Refer to the <code>java.lang.Object</code> documentation for the
|
||||
* interface contract.
|
||||
* Refer to the <code>java.lang.Object</code> documentation for the interface contract.
|
||||
*
|
||||
* @param obj to be compared
|
||||
*
|
||||
* @return <code>true</code> if the objects are equal, <code>false</code>
|
||||
* otherwise
|
||||
* @return <code>true</code> if the objects are equal, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean equals(Object obj);
|
||||
|
||||
/**
|
||||
* Refer to the <code>java.lang.Object</code> documentation for the
|
||||
* interface contract.
|
||||
* Refer to the <code>java.lang.Object</code> documentation for the interface contract.
|
||||
*
|
||||
* @return a hash code representation of this object
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,13 +30,12 @@ package org.acegisecurity.acl.basic;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AclObjectIdentityAware {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Retrieves the <code>AclObjectIdentity</code> for this instance.
|
||||
*
|
||||
* @return the ACL object identity for this instance (can never be
|
||||
* <code>null</code>)
|
||||
* @return the ACL object identity for this instance (can never be <code>null</code>)
|
||||
*/
|
||||
public AclObjectIdentity getAclObjectIdentity();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,24 +35,18 @@ package org.acegisecurity.acl.basic;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface BasicAclDao {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Obtains the ACLs that apply to the specified domain instance.
|
||||
*
|
||||
* <P>
|
||||
* Does <b>not</b> perform caching, include ACLs from any inheritance
|
||||
* hierarchy or filter returned objects based on effective permissions.
|
||||
* Implementations are solely responsible for returning ACLs found in the
|
||||
* ACL repository for the specified object identity.
|
||||
* </p>
|
||||
* Obtains the ACLs that apply to the specified domain instance.<P>Does <b>not</b> perform caching, include
|
||||
* ACLs from any inheritance hierarchy or filter returned objects based on effective permissions. Implementations
|
||||
* are solely responsible for returning ACLs found in the ACL repository for the specified object identity.</p>
|
||||
*
|
||||
* @param aclObjectIdentity the domain object instance that ACL information
|
||||
* is being requested for (never <code>null</code>)
|
||||
* @param aclObjectIdentity the domain object instance that ACL information is being requested for (never
|
||||
* <code>null</code>)
|
||||
*
|
||||
* @return the ACLs that apply (no <code>null</code>s are permitted in the
|
||||
* array), or <code>null</code> if no ACLs could be found for the
|
||||
* specified ACL object identity
|
||||
* @return the ACLs that apply (no <code>null</code>s are permitted in the array), or <code>null</code> if no ACLs
|
||||
* could be found for the specified ACL object identity
|
||||
*/
|
||||
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,50 +25,79 @@ import org.acegisecurity.acl.AclEntry;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface BasicAclEntry extends AclEntry {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* This setter should <B>only</B> be used by DAO implementations.
|
||||
* Indicates the domain object instance that is subject of this <code>BasicAclEntry</code>. This
|
||||
* information may be of interest to relying classes (voters and business methods) that wish to know the actual
|
||||
* origination of the ACL entry (so as to distinguish individual ACL entries from others contributed by the
|
||||
* inheritance hierarchy).
|
||||
*
|
||||
* @param aclObjectIdentity an object which can be used to uniquely
|
||||
* identify the domain object instance subject of this ACL entry
|
||||
*/
|
||||
public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity);
|
||||
|
||||
/**
|
||||
* Indicates the domain object instance that is subject of this
|
||||
* <code>BasicAclEntry</code>. This information may be of interest to
|
||||
* relying classes (voters and business methods) that wish to know the
|
||||
* actual origination of the ACL entry (so as to distinguish individual
|
||||
* ACL entries from others contributed by the inheritance hierarchy).
|
||||
*
|
||||
* @return the ACL object identity that is subject of this ACL entry (never
|
||||
* <code>null</code>)
|
||||
* @return the ACL object identity that is subject of this ACL entry (never <code>null</code>)
|
||||
*/
|
||||
public AclObjectIdentity getAclObjectIdentity();
|
||||
|
||||
/**
|
||||
* This setter should <B>only</B> be used by DAO implementations.
|
||||
* Indicates any ACL parent of the domain object instance. This is used by <code>BasicAclProvider</code> to
|
||||
* walk the inheritance hierarchy. An domain object instance need <b>not</b> have a parent.
|
||||
*
|
||||
* @param aclObjectParentIdentity an object which represents the parent of
|
||||
* the domain object instance subject of this ACL entry, or
|
||||
* <code>null</code> if either the domain object instance has no
|
||||
* parent or its parent should be not used to compute an
|
||||
* inheritance hierarchy
|
||||
*/
|
||||
public void setAclObjectParentIdentity(
|
||||
AclObjectIdentity aclObjectParentIdentity);
|
||||
|
||||
/**
|
||||
* Indicates any ACL parent of the domain object instance. This is used by
|
||||
* <code>BasicAclProvider</code> to walk the inheritance hierarchy. An
|
||||
* domain object instance need <b>not</b> have a parent.
|
||||
*
|
||||
* @return the ACL object identity that is the parent of this ACL entry
|
||||
* (may be <code>null</code> if no parent should be consulted)
|
||||
* @return the ACL object identity that is the parent of this ACL entry (may be <code>null</code> if no parent
|
||||
* should be consulted)
|
||||
*/
|
||||
public AclObjectIdentity getAclObjectParentIdentity();
|
||||
|
||||
/**
|
||||
* Access control lists in this package are based on bit masking. The integer value of the bit mask can be
|
||||
* obtained from this method.
|
||||
*
|
||||
* @return the bit mask applicable to this ACL entry (zero indicates a bit mask where no permissions have been
|
||||
* granted)
|
||||
*/
|
||||
public int getMask();
|
||||
|
||||
/**
|
||||
* A domain object instance will usually have multiple <code>BasicAclEntry</code>s. Each separate
|
||||
* <code>BasicAclEntry</code> applies to a particular "recipient". Typical examples of recipients include (but do
|
||||
* not necessarily have to include) usernames, role names, complex granted authorities etc.<P><B>It is
|
||||
* essential that only one <code>BasicAclEntry</code> exists for a given recipient</B>. Otherwise conflicts as to
|
||||
* the mask that should apply to a given recipient will occur.</p>
|
||||
* <P>This method indicates which recipient this <code>BasicAclEntry</code> applies to. The returned
|
||||
* object type will vary depending on the type of recipient. For instance, it might be a <code>String</code>
|
||||
* containing a username, or a <code>GrantedAuthorityImpl</code> containing a complex granted authority that is
|
||||
* being granted the permissions contained in this access control entry. The {@link EffectiveAclsResolver} and
|
||||
* {@link BasicAclProvider#getAcls(Object, Authentication)} can process the different recipient types and return
|
||||
* only those that apply to a specified <code>Authentication</code> object.</p>
|
||||
*
|
||||
* @return the recipient of this access control list entry (never <code>null</code>)
|
||||
*/
|
||||
public Object getRecipient();
|
||||
|
||||
/**
|
||||
* Determine if the mask of this entry includes this permission or not
|
||||
*
|
||||
* @param permissionToCheck
|
||||
*
|
||||
* @return if the entry's mask includes this permission
|
||||
*/
|
||||
public boolean isPermitted(int permissionToCheck);
|
||||
|
||||
/**
|
||||
* This setter should <B>only</B> be used by DAO implementations.
|
||||
*
|
||||
* @param aclObjectIdentity an object which can be used to uniquely identify the domain object instance subject of
|
||||
* this ACL entry
|
||||
*/
|
||||
public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity);
|
||||
|
||||
/**
|
||||
* This setter should <B>only</B> be used by DAO implementations.
|
||||
*
|
||||
* @param aclObjectParentIdentity an object which represents the parent of the domain object instance subject of
|
||||
* this ACL entry, or <code>null</code> if either the domain object instance has no parent or its parent
|
||||
* should be not used to compute an inheritance hierarchy
|
||||
*/
|
||||
public void setAclObjectParentIdentity(AclObjectIdentity aclObjectParentIdentity);
|
||||
|
||||
/**
|
||||
* This setter should <B>only</B> be used by DAO implementations.
|
||||
*
|
||||
@@ -76,59 +105,11 @@ public interface BasicAclEntry extends AclEntry {
|
||||
*/
|
||||
public void setMask(int mask);
|
||||
|
||||
/**
|
||||
* Access control lists in this package are based on bit masking. The
|
||||
* integer value of the bit mask can be obtained from this method.
|
||||
*
|
||||
* @return the bit mask applicable to this ACL entry (zero indicates a bit
|
||||
* mask where no permissions have been granted)
|
||||
*/
|
||||
public int getMask();
|
||||
|
||||
/**
|
||||
* This setter should <B>only</B> be used by DAO implementations.
|
||||
*
|
||||
* @param recipient a representation of the recipient of this ACL entry
|
||||
* that makes sense to an <code>EffectiveAclsResolver</code>
|
||||
* implementation
|
||||
* @param recipient a representation of the recipient of this ACL entry that makes sense to an
|
||||
* <code>EffectiveAclsResolver</code> implementation
|
||||
*/
|
||||
public void setRecipient(Object recipient);
|
||||
|
||||
/**
|
||||
* A domain object instance will usually have multiple
|
||||
* <code>BasicAclEntry</code>s. Each separate <code>BasicAclEntry</code>
|
||||
* applies to a particular "recipient". Typical examples of recipients
|
||||
* include (but do not necessarily have to include) usernames, role names,
|
||||
* complex granted authorities etc.
|
||||
*
|
||||
* <P>
|
||||
* <B>It is essential that only one <code>BasicAclEntry</code> exists for a
|
||||
* given recipient</B>. Otherwise conflicts as to the mask that should
|
||||
* apply to a given recipient will occur.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* This method indicates which recipient this <code>BasicAclEntry</code>
|
||||
* applies to. The returned object type will vary depending on the type of
|
||||
* recipient. For instance, it might be a <code>String</code> containing a
|
||||
* username, or a <code>GrantedAuthorityImpl</code> containing a complex
|
||||
* granted authority that is being granted the permissions contained in
|
||||
* this access control entry. The {@link EffectiveAclsResolver} and {@link
|
||||
* BasicAclProvider#getAcls(Object, Authentication)} can process the
|
||||
* different recipient types and return only those that apply to a
|
||||
* specified <code>Authentication</code> object.
|
||||
* </p>
|
||||
*
|
||||
* @return the recipient of this access control list entry (never
|
||||
* <code>null</code>)
|
||||
*/
|
||||
public Object getRecipient();
|
||||
|
||||
/**
|
||||
* Determine if the mask of this entry includes this permission or not
|
||||
*
|
||||
* @param permissionToCheck
|
||||
* @return if the entry's mask includes this permission
|
||||
*/
|
||||
public boolean isPermitted(int permissionToCheck);
|
||||
}
|
||||
|
||||
@@ -31,37 +31,29 @@ package org.acegisecurity.acl.basic;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface BasicAclEntryCache {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Obtains an array of {@link BasicAclEntry}s from the cache.
|
||||
*
|
||||
* @param aclObjectIdentity which should be obtained from the cache
|
||||
*
|
||||
* @return any applicable <code>BasicAclEntry</code>s (no
|
||||
* <code>null</code>s are permitted in the returned array) or
|
||||
* <code>null</code> if the object identity could not be found or
|
||||
* if the cache entry has expired
|
||||
* @return any applicable <code>BasicAclEntry</code>s (no <code>null</code>s are permitted in the returned array)
|
||||
* or <code>null</code> if the object identity could not be found or if the cache entry has expired
|
||||
*/
|
||||
public BasicAclEntry[] getEntriesFromCache(
|
||||
AclObjectIdentity aclObjectIdentity);
|
||||
public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity);
|
||||
|
||||
/**
|
||||
* Places an array of {@link BasicAclEntry}s in the cache.
|
||||
*
|
||||
* <P>
|
||||
* No <code>null</code>s are allowed in the passed array. If any
|
||||
* <code>null</code> is passed, the implementation may throw an exception.
|
||||
* </p>
|
||||
* Places an array of {@link BasicAclEntry}s in the cache.<P>No <code>null</code>s are allowed in the
|
||||
* passed array. If any <code>null</code> is passed, the implementation may throw an exception.</p>
|
||||
*
|
||||
* @param basicAclEntry the ACL entries to cache (the key will be extracted
|
||||
* from the {@link BasicAclEntry#getAclObjectIdentity()} method
|
||||
* @param basicAclEntry the ACL entries to cache (the key will be extracted from the {@link
|
||||
* BasicAclEntry#getAclObjectIdentity()} method
|
||||
*/
|
||||
public void putEntriesInCache(BasicAclEntry[] basicAclEntry);
|
||||
|
||||
/**
|
||||
* Removes all ACL entries related to an {@link AclObjectIdentity} from the
|
||||
* cache.
|
||||
* Removes all ACL entries related to an {@link AclObjectIdentity} from the cache.
|
||||
*
|
||||
* @param aclObjectIdentity which should be removed from the cache
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@ package org.acegisecurity.acl.basic;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a more extensive data access object
|
||||
* for {@link BasicAclEntry}s.
|
||||
@@ -30,35 +31,42 @@ import org.springframework.dao.DataAccessException;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface BasicAclExtendedDao extends BasicAclDao {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void create(BasicAclEntry basicAclEntry) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Deletes <b>all</b> entries associated with the
|
||||
* specified <code>AclObjectIdentity</code>.
|
||||
*
|
||||
* @param aclObjectIdentity to delete, including any <code>BasicAclEntry</code>s
|
||||
*/
|
||||
public void delete(AclObjectIdentity aclObjectIdentity) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Deletes the <code>BasicAclEntry</code> associated with the specified
|
||||
* <code>AclObjectIdentity</code> and recipient <code>Object</code>.
|
||||
*
|
||||
* @param aclObjectIdentity to delete
|
||||
* @param recipient to delete
|
||||
*/
|
||||
public void delete(AclObjectIdentity aclObjectIdentity, Object recipient) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Changes the permission mask assigned to the <code>BasicAclEntry</code>
|
||||
* associated with the specified
|
||||
* <code>AclObjectIdentity</code> and recipient <code>Object</code>.
|
||||
*
|
||||
* @param aclObjectIdentity to locate the relevant <code>BasicAclEntry</code>
|
||||
* @param recipient to locate the relevant <code>BasicAclEntry</code>
|
||||
* @param newMask indicating the new permission
|
||||
*/
|
||||
public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask) throws DataAccessException;
|
||||
/**
|
||||
* Changes the permission mask assigned to the <code>BasicAclEntry</code> associated with the specified
|
||||
* <code>AclObjectIdentity</code> and recipient <code>Object</code>.
|
||||
*
|
||||
* @param aclObjectIdentity to locate the relevant <code>BasicAclEntry</code>
|
||||
* @param recipient to locate the relevant <code>BasicAclEntry</code>
|
||||
* @param newMask indicating the new permission
|
||||
*
|
||||
* @throws DataAccessException DOCUMENT ME!
|
||||
*/
|
||||
public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask)
|
||||
throws DataAccessException;
|
||||
|
||||
public void create(BasicAclEntry basicAclEntry) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Deletes <b>all</b> entries associated with the specified <code>AclObjectIdentity</code>.
|
||||
*
|
||||
* @param aclObjectIdentity to delete, including any <code>BasicAclEntry</code>s
|
||||
*
|
||||
* @throws DataAccessException DOCUMENT ME!
|
||||
*/
|
||||
public void delete(AclObjectIdentity aclObjectIdentity)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Deletes the <code>BasicAclEntry</code> associated with the specified <code>AclObjectIdentity</code> and
|
||||
* recipient <code>Object</code>.
|
||||
*
|
||||
* @param aclObjectIdentity to delete
|
||||
* @param recipient to delete
|
||||
*
|
||||
* @throws DataAccessException DOCUMENT ME!
|
||||
*/
|
||||
public void delete(AclObjectIdentity aclObjectIdentity, Object recipient)
|
||||
throws DataAccessException;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.acegisecurity.acl.basic;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
|
||||
import org.acegisecurity.acl.AclEntry;
|
||||
import org.acegisecurity.acl.AclProvider;
|
||||
import org.acegisecurity.acl.basic.cache.NullAclEntryCache;
|
||||
@@ -24,6 +25,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
@@ -34,70 +36,59 @@ import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* Retrieves access control lists (ACL) entries for domain object instances
|
||||
* from a data access object (DAO).
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* This implementation will provide ACL lookup services for any object that it
|
||||
* can determine the {@link AclObjectIdentity} for by calling the {@link
|
||||
* #obtainIdentity(Object)} method. Subclasses can override this method if
|
||||
* they only want the <code>BasicAclProvider</code> responding to particular
|
||||
* domain object instances.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* <code>BasicAclProvider</code> will walk an inheritance hierarchy if a
|
||||
* <code>BasicAclEntry</code> returned by the DAO indicates it has a parent.
|
||||
* NB: inheritance occurs at a <I>domain instance object</I> level. It does
|
||||
* not occur at an ACL recipient level. This means
|
||||
* <B>all</B><code>BasicAclEntry</code>s for a given domain instance object
|
||||
* <B>must</B> have the <B>same</B> parent identity, or
|
||||
* <B>all</B><code>BasicAclEntry</code>s must have <code>null</code> as their
|
||||
* parent identity.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* A cache should be used. This is provided by the {@link BasicAclEntryCache}.
|
||||
* <code>BasicAclProvider</code> by default is setup to use the {@link
|
||||
* NullAclEntryCache}, which performs no caching.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* To implement the {@link #getAcls(Object, Authentication)} method,
|
||||
* <code>BasicAclProvider</code> requires a {@link EffectiveAclsResolver} to
|
||||
* be configured against it. By default the {@link
|
||||
* GrantedAuthorityEffectiveAclsResolver} is used.
|
||||
* </p>
|
||||
* <P>Retrieves access control lists (ACL) entries for domain object instances from a data access object (DAO).</p>
|
||||
* <P>This implementation will provide ACL lookup services for any object that it can determine the {@link
|
||||
* AclObjectIdentity} for by calling the {@link #obtainIdentity(Object)} method. Subclasses can override this method
|
||||
* if they only want the <code>BasicAclProvider</code> responding to particular domain object instances.</p>
|
||||
* <P><code>BasicAclProvider</code> will walk an inheritance hierarchy if a <code>BasicAclEntry</code> returned by
|
||||
* the DAO indicates it has a parent. NB: inheritance occurs at a <I>domain instance object</I> level. It does not
|
||||
* occur at an ACL recipient level. This means <B>all</B><code>BasicAclEntry</code>s for a given domain instance
|
||||
* object <B>must</B> have the <B>same</B> parent identity, or <B>all</B><code>BasicAclEntry</code>s must have
|
||||
* <code>null</code> as their parent identity.</p>
|
||||
* <P>A cache should be used. This is provided by the {@link BasicAclEntryCache}. <code>BasicAclProvider</code> by
|
||||
* default is setup to use the {@link NullAclEntryCache}, which performs no caching.</p>
|
||||
* <P>To implement the {@link #getAcls(Object, Authentication)} method, <code>BasicAclProvider</code> requires a
|
||||
* {@link EffectiveAclsResolver} to be configured against it. By default the {@link
|
||||
* GrantedAuthorityEffectiveAclsResolver} is used.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BasicAclProvider implements AclProvider, InitializingBean {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(BasicAclProvider.class);
|
||||
|
||||
/**
|
||||
* Marker added to the cache to indicate an AclObjectIdentity has no
|
||||
* corresponding BasicAclEntry[]s
|
||||
*/
|
||||
/** Marker added to the cache to indicate an AclObjectIdentity has no corresponding BasicAclEntry[]s */
|
||||
private static String RECIPIENT_FOR_CACHE_EMPTY = "RESERVED_RECIPIENT_NOBODY";
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
/**
|
||||
* Must be set to an appropriate data access object. Defaults to
|
||||
* <code>null</code>.
|
||||
*/
|
||||
/** Must be set to an appropriate data access object. Defaults to <code>null</code>. */
|
||||
private BasicAclDao basicAclDao;
|
||||
private BasicAclEntryCache basicAclEntryCache = new NullAclEntryCache();
|
||||
private Class defaultAclObjectIdentityClass = NamedEntityObjectIdentity.class;
|
||||
private Class restrictSupportToClass = null;
|
||||
private EffectiveAclsResolver effectiveAclsResolver = new GrantedAuthorityEffectiveAclsResolver();
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
Assert.notNull(basicAclDao, "basicAclDao required");
|
||||
Assert.notNull(basicAclEntryCache, "basicAclEntryCache required");
|
||||
Assert.notNull(basicAclEntryCache, "basicAclEntryCache required");
|
||||
Assert.notNull(effectiveAclsResolver, "effectiveAclsResolver required");
|
||||
Assert.notNull(defaultAclObjectIdentityClass, "defaultAclObjectIdentityClass required");
|
||||
Assert.isTrue(AclObjectIdentity.class.isAssignableFrom(this.defaultAclObjectIdentityClass),
|
||||
"defaultAclObjectIdentityClass must implement AclObjectIdentity");
|
||||
|
||||
try {
|
||||
Constructor constructor = defaultAclObjectIdentityClass.getConstructor(new Class[] {Object.class});
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
throw new IllegalArgumentException(
|
||||
"defaultAclObjectIdentityClass must provide a constructor that accepts the domain object instance!");
|
||||
}
|
||||
}
|
||||
|
||||
public AclEntry[] getAcls(Object domainInstance) {
|
||||
Map map = new HashMap();
|
||||
@@ -120,15 +111,13 @@ public class BasicAclProvider implements AclProvider, InitializingBean {
|
||||
// Add the leaf objects to the Map, keyed on recipient
|
||||
for (int i = 0; i < instanceAclEntries.length; i++) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Explicit add: "
|
||||
+ instanceAclEntries[i].toString());
|
||||
logger.debug("Explicit add: " + instanceAclEntries[i].toString());
|
||||
}
|
||||
|
||||
map.put(instanceAclEntries[i].getRecipient(), instanceAclEntries[i]);
|
||||
}
|
||||
|
||||
AclObjectIdentity parent = instanceAclEntries[0]
|
||||
.getAclObjectParentIdentity();
|
||||
AclObjectIdentity parent = instanceAclEntries[0].getAclObjectParentIdentity();
|
||||
|
||||
while (parent != null) {
|
||||
BasicAclEntry[] parentAclEntries = lookup(parent);
|
||||
@@ -150,16 +139,13 @@ public class BasicAclProvider implements AclProvider, InitializingBean {
|
||||
for (int i = 0; i < parentAclEntries.length; i++) {
|
||||
if (!map.containsKey(parentAclEntries[i].getRecipient())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Added parent to map: "
|
||||
+ parentAclEntries[i].toString());
|
||||
logger.debug("Added parent to map: " + parentAclEntries[i].toString());
|
||||
}
|
||||
|
||||
map.put(parentAclEntries[i].getRecipient(),
|
||||
parentAclEntries[i]);
|
||||
map.put(parentAclEntries[i].getRecipient(), parentAclEntries[i]);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Did NOT add parent to map: "
|
||||
+ parentAclEntries[i].toString());
|
||||
logger.debug("Did NOT add parent to map: " + parentAclEntries[i].toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,211 +156,35 @@ public class BasicAclProvider implements AclProvider, InitializingBean {
|
||||
|
||||
Collection collection = map.values();
|
||||
|
||||
return (AclEntry[]) collection.toArray(new AclEntry[]{});
|
||||
return (AclEntry[]) collection.toArray(new AclEntry[] {});
|
||||
}
|
||||
|
||||
public AclEntry[] getAcls(Object domainInstance,
|
||||
Authentication authentication) {
|
||||
public AclEntry[] getAcls(Object domainInstance, Authentication authentication) {
|
||||
AclEntry[] allAcls = (AclEntry[]) this.getAcls(domainInstance);
|
||||
|
||||
return this.effectiveAclsResolver.resolveEffectiveAcls(allAcls,
|
||||
authentication);
|
||||
}
|
||||
|
||||
public void setBasicAclDao(BasicAclDao basicAclDao) {
|
||||
this.basicAclDao = basicAclDao;
|
||||
return this.effectiveAclsResolver.resolveEffectiveAcls(allAcls, authentication);
|
||||
}
|
||||
|
||||
public BasicAclDao getBasicAclDao() {
|
||||
return basicAclDao;
|
||||
}
|
||||
|
||||
public void setBasicAclEntryCache(BasicAclEntryCache basicAclEntryCache) {
|
||||
this.basicAclEntryCache = basicAclEntryCache;
|
||||
}
|
||||
|
||||
public BasicAclEntryCache getBasicAclEntryCache() {
|
||||
return basicAclEntryCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows selection of the <code>AclObjectIdentity</code> class that an
|
||||
* attempt should be made to construct if the passed object does not
|
||||
* implement <code>AclObjectIdentityAware</code>.
|
||||
*
|
||||
* <P>
|
||||
* NB: Any <code>defaultAclObjectIdentityClass</code><b>must</b> provide a
|
||||
* public constructor that accepts an <code>Object</code>. Otherwise it is
|
||||
* not possible for the <code>BasicAclProvider</code> to try to create the
|
||||
* <code>AclObjectIdentity</code> instance at runtime.
|
||||
* </p>
|
||||
*
|
||||
* @param defaultAclObjectIdentityClass
|
||||
*/
|
||||
public void setDefaultAclObjectIdentityClass(
|
||||
Class defaultAclObjectIdentityClass) {
|
||||
this.defaultAclObjectIdentityClass = defaultAclObjectIdentityClass;
|
||||
}
|
||||
|
||||
public Class getDefaultAclObjectIdentityClass() {
|
||||
return defaultAclObjectIdentityClass;
|
||||
}
|
||||
|
||||
public void setEffectiveAclsResolver(
|
||||
EffectiveAclsResolver effectiveAclsResolver) {
|
||||
this.effectiveAclsResolver = effectiveAclsResolver;
|
||||
}
|
||||
|
||||
public EffectiveAclsResolver getEffectiveAclsResolver() {
|
||||
return effectiveAclsResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to a value other than <code>null</code>, the {@link
|
||||
* #supports(Object)} method will <b>only</b> support the indicates class.
|
||||
* This is useful if you wish to wire multiple
|
||||
* <code>BasicAclProvider</code>s in a list of
|
||||
* <code>AclProviderManager.providers</code> but only have particular
|
||||
* instances respond to particular domain object types.
|
||||
*
|
||||
* @param restrictSupportToClass the class to restrict this
|
||||
* <code>BasicAclProvider</code> to service request for, or
|
||||
* <code>null</code> (the default) if the
|
||||
* <code>BasicAclProvider</code> should respond to every class
|
||||
* presented
|
||||
*/
|
||||
public void setRestrictSupportToClass(Class restrictSupportToClass) {
|
||||
this.restrictSupportToClass = restrictSupportToClass;
|
||||
}
|
||||
|
||||
public Class getRestrictSupportToClass() {
|
||||
return restrictSupportToClass;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
Assert.notNull(basicAclDao, "basicAclDao required");
|
||||
Assert.notNull(basicAclEntryCache, "basicAclEntryCache required");
|
||||
Assert.notNull(basicAclEntryCache, "basicAclEntryCache required");
|
||||
Assert.notNull(effectiveAclsResolver, "effectiveAclsResolver required");
|
||||
Assert.notNull(defaultAclObjectIdentityClass, "defaultAclObjectIdentityClass required");
|
||||
Assert.isTrue(AclObjectIdentity.class.isAssignableFrom(this.defaultAclObjectIdentityClass),
|
||||
"defaultAclObjectIdentityClass must implement AclObjectIdentity");
|
||||
|
||||
try {
|
||||
Constructor constructor = defaultAclObjectIdentityClass
|
||||
.getConstructor(new Class[]{Object.class});
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
throw new IllegalArgumentException("defaultAclObjectIdentityClass must provide a constructor that accepts the domain object instance!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates support for the passed object.
|
||||
*
|
||||
* <p>
|
||||
* An object will only be supported if it (i) is allowed to be supported as
|
||||
* defined by the {@link #setRestrictSupportToClass(Class)} method,
|
||||
* <b>and</b> (ii) if an <code>AclObjectIdentity</code> is returned by
|
||||
* {@link #obtainIdentity(Object)} for that object.
|
||||
* </p>
|
||||
*
|
||||
* @param domainInstance the instance to check
|
||||
*
|
||||
* @return <code>true</code> if this provider supports the passed object,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean supports(Object domainInstance) {
|
||||
if (domainInstance == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("domainInstance is null");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((restrictSupportToClass != null)
|
||||
&& !restrictSupportToClass.isAssignableFrom(
|
||||
domainInstance.getClass())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("domainInstance not instance of "
|
||||
+ restrictSupportToClass);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obtainIdentity(domainInstance) == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("obtainIdentity returned null");
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("obtainIdentity returned "
|
||||
+ obtainIdentity(domainInstance));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method looks up the <code>AclObjectIdentity</code> of a passed
|
||||
* domain object instance.
|
||||
*
|
||||
* <P>
|
||||
* This implementation attempts to obtain the
|
||||
* <code>AclObjectIdentity</code> via reflection inspection of the class
|
||||
* for the {@link AclObjectIdentityAware} interface. If this fails, an
|
||||
* attempt is made to construct a {@link
|
||||
* #getDefaultAclObjectIdentityClass()} object by passing the domain
|
||||
* instance object into its constructor.
|
||||
* </p>
|
||||
*
|
||||
* @param domainInstance the domain object instance (never
|
||||
* <code>null</code>)
|
||||
*
|
||||
* @return an ACL object identity, or <code>null</code> if one could not be
|
||||
* obtained
|
||||
*/
|
||||
protected AclObjectIdentity obtainIdentity(Object domainInstance) {
|
||||
if (domainInstance instanceof AclObjectIdentityAware) {
|
||||
AclObjectIdentityAware aclObjectIdentityAware = (AclObjectIdentityAware) domainInstance;
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("domainInstance: " + domainInstance
|
||||
+ " cast to AclObjectIdentityAware");
|
||||
}
|
||||
|
||||
return aclObjectIdentityAware.getAclObjectIdentity();
|
||||
}
|
||||
|
||||
try {
|
||||
Constructor constructor = defaultAclObjectIdentityClass
|
||||
.getConstructor(new Class[] {Object.class});
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("domainInstance: " + domainInstance
|
||||
+ " attempting to pass to constructor: " + constructor);
|
||||
}
|
||||
|
||||
return (AclObjectIdentity) constructor.newInstance(new Object[] {domainInstance});
|
||||
} catch (Exception ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Error attempting construction of "
|
||||
+ defaultAclObjectIdentityClass + ": " + ex.getMessage(), ex);
|
||||
|
||||
if (ex.getCause() != null) {
|
||||
logger.debug("Cause: " + ex.getCause().getMessage(),
|
||||
ex.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private BasicAclEntry[] lookup(AclObjectIdentity aclObjectIdentity) {
|
||||
BasicAclEntry[] result = basicAclEntryCache.getEntriesFromCache(aclObjectIdentity);
|
||||
|
||||
@@ -389,8 +199,9 @@ public class BasicAclProvider implements AclProvider, InitializingBean {
|
||||
result = basicAclDao.getAcls(aclObjectIdentity);
|
||||
|
||||
if (result == null) {
|
||||
SimpleAclEntry[] emptyAclEntries = {new SimpleAclEntry(RECIPIENT_FOR_CACHE_EMPTY,
|
||||
aclObjectIdentity, null, 0)};
|
||||
SimpleAclEntry[] emptyAclEntries = {
|
||||
new SimpleAclEntry(RECIPIENT_FOR_CACHE_EMPTY, aclObjectIdentity, null, 0)
|
||||
};
|
||||
basicAclEntryCache.putEntriesInCache(emptyAclEntries);
|
||||
|
||||
return null;
|
||||
@@ -400,4 +211,127 @@ public class BasicAclProvider implements AclProvider, InitializingBean {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method looks up the <code>AclObjectIdentity</code> of a passed domain object instance.<P>This
|
||||
* implementation attempts to obtain the <code>AclObjectIdentity</code> via reflection inspection of the class for
|
||||
* the {@link AclObjectIdentityAware} interface. If this fails, an attempt is made to construct a {@link
|
||||
* #getDefaultAclObjectIdentityClass()} object by passing the domain instance object into its constructor.</p>
|
||||
*
|
||||
* @param domainInstance the domain object instance (never <code>null</code>)
|
||||
*
|
||||
* @return an ACL object identity, or <code>null</code> if one could not be obtained
|
||||
*/
|
||||
protected AclObjectIdentity obtainIdentity(Object domainInstance) {
|
||||
if (domainInstance instanceof AclObjectIdentityAware) {
|
||||
AclObjectIdentityAware aclObjectIdentityAware = (AclObjectIdentityAware) domainInstance;
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("domainInstance: " + domainInstance + " cast to AclObjectIdentityAware");
|
||||
}
|
||||
|
||||
return aclObjectIdentityAware.getAclObjectIdentity();
|
||||
}
|
||||
|
||||
try {
|
||||
Constructor constructor = defaultAclObjectIdentityClass.getConstructor(new Class[] {Object.class});
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("domainInstance: " + domainInstance + " attempting to pass to constructor: " + constructor);
|
||||
}
|
||||
|
||||
return (AclObjectIdentity) constructor.newInstance(new Object[] {domainInstance});
|
||||
} catch (Exception ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Error attempting construction of " + defaultAclObjectIdentityClass + ": "
|
||||
+ ex.getMessage(), ex);
|
||||
|
||||
if (ex.getCause() != null) {
|
||||
logger.debug("Cause: " + ex.getCause().getMessage(), ex.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setBasicAclDao(BasicAclDao basicAclDao) {
|
||||
this.basicAclDao = basicAclDao;
|
||||
}
|
||||
|
||||
public void setBasicAclEntryCache(BasicAclEntryCache basicAclEntryCache) {
|
||||
this.basicAclEntryCache = basicAclEntryCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows selection of the <code>AclObjectIdentity</code> class that an attempt should be made to construct
|
||||
* if the passed object does not implement <code>AclObjectIdentityAware</code>.<P>NB: Any
|
||||
* <code>defaultAclObjectIdentityClass</code><b>must</b> provide a public constructor that accepts an
|
||||
* <code>Object</code>. Otherwise it is not possible for the <code>BasicAclProvider</code> to try to create the
|
||||
* <code>AclObjectIdentity</code> instance at runtime.</p>
|
||||
*
|
||||
* @param defaultAclObjectIdentityClass
|
||||
*/
|
||||
public void setDefaultAclObjectIdentityClass(Class defaultAclObjectIdentityClass) {
|
||||
this.defaultAclObjectIdentityClass = defaultAclObjectIdentityClass;
|
||||
}
|
||||
|
||||
public void setEffectiveAclsResolver(EffectiveAclsResolver effectiveAclsResolver) {
|
||||
this.effectiveAclsResolver = effectiveAclsResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to a value other than <code>null</code>, the {@link #supports(Object)} method will <b>only</b>
|
||||
* support the indicates class. This is useful if you wish to wire multiple <code>BasicAclProvider</code>s in a
|
||||
* list of <code>AclProviderManager.providers</code> but only have particular instances respond to particular
|
||||
* domain object types.
|
||||
*
|
||||
* @param restrictSupportToClass the class to restrict this <code>BasicAclProvider</code> to service request for,
|
||||
* or <code>null</code> (the default) if the <code>BasicAclProvider</code> should respond to every class
|
||||
* presented
|
||||
*/
|
||||
public void setRestrictSupportToClass(Class restrictSupportToClass) {
|
||||
this.restrictSupportToClass = restrictSupportToClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates support for the passed object.<p>An object will only be supported if it (i) is allowed to be
|
||||
* supported as defined by the {@link #setRestrictSupportToClass(Class)} method, <b>and</b> (ii) if an
|
||||
* <code>AclObjectIdentity</code> is returned by {@link #obtainIdentity(Object)} for that object.</p>
|
||||
*
|
||||
* @param domainInstance the instance to check
|
||||
*
|
||||
* @return <code>true</code> if this provider supports the passed object, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean supports(Object domainInstance) {
|
||||
if (domainInstance == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("domainInstance is null");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((restrictSupportToClass != null) && !restrictSupportToClass.isAssignableFrom(domainInstance.getClass())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("domainInstance not instance of " + restrictSupportToClass);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obtainIdentity(domainInstance) == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("obtainIdentity returned null");
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("obtainIdentity returned " + obtainIdentity(domainInstance));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.acegisecurity.acl.basic;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
|
||||
import org.acegisecurity.acl.AclEntry;
|
||||
|
||||
|
||||
@@ -45,21 +46,16 @@ import org.acegisecurity.acl.AclEntry;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface EffectiveAclsResolver {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Determines the ACLs that apply to the presented
|
||||
* <code>Authentication</code> object.
|
||||
* Determines the ACLs that apply to the presented <code>Authentication</code> object.
|
||||
*
|
||||
* @param allAcls every ACL assigned to a domain object instance
|
||||
* @param filteredBy the principal (populated with
|
||||
* <code>GrantedAuthority</code>s along with any other members that
|
||||
* relate to role or group membership) that effective ACLs should
|
||||
* be returned for
|
||||
* @param filteredBy the principal (populated with <code>GrantedAuthority</code>s along with any other members that
|
||||
* relate to role or group membership) that effective ACLs should be returned for
|
||||
*
|
||||
* @return the ACLs that apply to the presented principal, or
|
||||
* <code>null</code> if there are none after filtering
|
||||
* @return the ACLs that apply to the presented principal, or <code>null</code> if there are none after filtering
|
||||
*/
|
||||
public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls,
|
||||
Authentication filteredBy);
|
||||
public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, Authentication filteredBy);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,9 @@ package org.acegisecurity.acl.basic;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
|
||||
import org.acegisecurity.acl.AclEntry;
|
||||
|
||||
import org.acegisecurity.userdetails.UserDetails;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -28,45 +30,29 @@ import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link EffectiveAclsResolver}.
|
||||
*
|
||||
* <P>
|
||||
* This implementation does not need to understand the "recipient" types
|
||||
* presented in a <code>BasicAclEntry</code> because it merely delegates to
|
||||
* the detected {@link Authentication#getPrincipal()} or {@link
|
||||
* Authentication#getAuthorities()}. The principal object or granted
|
||||
* authorities object has its <code>Object.equals(recipient)</code> method
|
||||
* called to make the decision as to whether the recipient in the
|
||||
* <code>BasicAclEntry</code> is the same as the principal or granted
|
||||
* authority.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* This class should prove an adequate ACLs resolver if you're using standard
|
||||
* Acegi Security classes. This is because the typical
|
||||
* <code>Authentication</code> token is
|
||||
* <code>UsernamePasswordAuthenticationToken</code>, which for its
|
||||
* <code>principal</code> is usually a <code>String</code>. The
|
||||
* <code>GrantedAuthorityImpl</code> is typically used for granted
|
||||
* authorities, which tests for equality based on a <code>String</code>. This
|
||||
* means <code>BasicAclDao</code>s simply need to return a <code>String</code>
|
||||
* to represent the recipient. If you use non-<code>String</code> objects, you
|
||||
* will probably require an alternative <code>EffectiveAclsResolver</code>.
|
||||
* </p>
|
||||
* Simple implementation of {@link EffectiveAclsResolver}.<P>This implementation does not need to understand the
|
||||
* "recipient" types presented in a <code>BasicAclEntry</code> because it merely delegates to the detected {@link
|
||||
* Authentication#getPrincipal()} or {@link Authentication#getAuthorities()}. The principal object or granted
|
||||
* authorities object has its <code>Object.equals(recipient)</code> method called to make the decision as to whether
|
||||
* the recipient in the <code>BasicAclEntry</code> is the same as the principal or granted authority.</p>
|
||||
* <P>This class should prove an adequate ACLs resolver if you're using standard Acegi Security classes. This is
|
||||
* because the typical <code>Authentication</code> token is <code>UsernamePasswordAuthenticationToken</code>, which
|
||||
* for its <code>principal</code> is usually a <code>String</code>. The <code>GrantedAuthorityImpl</code> is typically
|
||||
* used for granted authorities, which tests for equality based on a <code>String</code>. This means
|
||||
* <code>BasicAclDao</code>s simply need to return a <code>String</code> to represent the recipient. If you use
|
||||
* non-<code>String</code> objects, you will probably require an alternative <code>EffectiveAclsResolver</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class GrantedAuthorityEffectiveAclsResolver
|
||||
implements EffectiveAclsResolver {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class GrantedAuthorityEffectiveAclsResolver implements EffectiveAclsResolver {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(GrantedAuthorityEffectiveAclsResolver.class);
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls,
|
||||
Authentication filteredBy) {
|
||||
public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, Authentication filteredBy) {
|
||||
if ((allAcls == null) || (allAcls.length == 0)) {
|
||||
return null;
|
||||
}
|
||||
@@ -74,8 +60,7 @@ public class GrantedAuthorityEffectiveAclsResolver
|
||||
List list = new Vector();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Locating AclEntry[]s (from set of "
|
||||
+ ((allAcls == null) ? 0 : allAcls.length)
|
||||
logger.debug("Locating AclEntry[]s (from set of " + ((allAcls == null) ? 0 : allAcls.length)
|
||||
+ ") that apply to Authentication: " + filteredBy);
|
||||
}
|
||||
|
||||
@@ -84,26 +69,21 @@ public class GrantedAuthorityEffectiveAclsResolver
|
||||
continue;
|
||||
}
|
||||
|
||||
Object recipient = ((BasicAclEntry) allAcls[i])
|
||||
.getRecipient();
|
||||
Object recipient = ((BasicAclEntry) allAcls[i]).getRecipient();
|
||||
|
||||
// Allow the Authentication's getPrincipal to decide whether
|
||||
// the presented recipient is "equal" (allows BasicAclDaos to
|
||||
// return Strings rather than proper objects in simple cases)
|
||||
if (filteredBy.getPrincipal().equals(recipient)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Principal matches AclEntry recipient: "
|
||||
+ recipient);
|
||||
logger.debug("Principal matches AclEntry recipient: " + recipient);
|
||||
}
|
||||
|
||||
list.add(allAcls[i]);
|
||||
} else if (filteredBy.getPrincipal() instanceof UserDetails
|
||||
&& ((UserDetails) filteredBy.getPrincipal()).getUsername()
|
||||
.equals(recipient)) {
|
||||
&& ((UserDetails) filteredBy.getPrincipal()).getUsername().equals(recipient)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Principal (from UserDetails) matches AclEntry recipient: "
|
||||
+ recipient);
|
||||
logger.debug("Principal (from UserDetails) matches AclEntry recipient: " + recipient);
|
||||
}
|
||||
|
||||
list.add(allAcls[i]);
|
||||
@@ -127,8 +107,7 @@ public class GrantedAuthorityEffectiveAclsResolver
|
||||
for (int k = 0; k < authorities.length; k++) {
|
||||
if (authorities[k].equals(recipient)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("GrantedAuthority: " + authorities[k]
|
||||
+ " matches recipient: " + recipient);
|
||||
logger.debug("GrantedAuthority: " + authorities[k] + " matches recipient: " + recipient);
|
||||
}
|
||||
|
||||
list.add(allAcls[i]);
|
||||
@@ -140,15 +119,13 @@ public class GrantedAuthorityEffectiveAclsResolver
|
||||
// return null if appropriate (as per interface contract)
|
||||
if (list.size() > 0) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Returning effective AclEntry array with "
|
||||
+ list.size() + " elements");
|
||||
logger.debug("Returning effective AclEntry array with " + list.size() + " elements");
|
||||
}
|
||||
|
||||
return (BasicAclEntry[]) list.toArray(new BasicAclEntry[] {});
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Returning null AclEntry array as zero effective AclEntrys found");
|
||||
logger.debug("Returning null AclEntry array as zero effective AclEntrys found");
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -23,21 +23,16 @@ import java.lang.reflect.Method;
|
||||
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link AclObjectIdentity}.
|
||||
*
|
||||
* <P>
|
||||
* Uses <code>String</code>s to store the identity of the domain object
|
||||
* instance. Also offers a constructor that uses reflection to build the
|
||||
* identity information.
|
||||
* </p>
|
||||
* Simple implementation of {@link AclObjectIdentity}.<P>Uses <code>String</code>s to store the identity of the
|
||||
* domain object instance. Also offers a constructor that uses reflection to build the identity information.</p>
|
||||
*/
|
||||
public class NamedEntityObjectIdentity implements AclObjectIdentity {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private String classname;
|
||||
private String id;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public NamedEntityObjectIdentity(String classname, String id) {
|
||||
Assert.hasText(classname, "classname required");
|
||||
@@ -46,7 +41,7 @@ public class NamedEntityObjectIdentity implements AclObjectIdentity {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Creates the <code>NamedEntityObjectIdentity</code> based on the passed
|
||||
* object instance. The passed object must provide a <code>getId()</code>
|
||||
* method, otherwise an exception will be thrown.
|
||||
@@ -57,15 +52,13 @@ public class NamedEntityObjectIdentity implements AclObjectIdentity {
|
||||
* @throws InvocationTargetException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public NamedEntityObjectIdentity(Object object)
|
||||
throws IllegalAccessException, InvocationTargetException {
|
||||
public NamedEntityObjectIdentity(Object object) throws IllegalAccessException, InvocationTargetException {
|
||||
Assert.notNull(object, "object cannot be null");
|
||||
|
||||
this.classname = (getPackageName(object.getClass().getName()) == null)
|
||||
? ClassUtils.getShortName(object.getClass())
|
||||
: getPackageName(object.getClass().getName()) + "."
|
||||
+ ClassUtils.getShortName(object.getClass());
|
||||
|
||||
? ClassUtils.getShortName(object.getClass())
|
||||
: (getPackageName(object.getClass().getName()) + "." + ClassUtils.getShortName(object.getClass()));
|
||||
|
||||
Class clazz = object.getClass();
|
||||
|
||||
try {
|
||||
@@ -78,15 +71,11 @@ public class NamedEntityObjectIdentity implements AclObjectIdentity {
|
||||
}
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Important so caching operates properly.
|
||||
*
|
||||
* <P>
|
||||
* Considers an object of the same class equal if it has the same
|
||||
* <code>classname</code> and <code>id</code> properties.
|
||||
* </p>
|
||||
* Important so caching operates properly.<P>Considers an object of the same class equal if it has the same
|
||||
* <code>classname</code> and <code>id</code> properties.</p>
|
||||
*
|
||||
* @param arg0 object to compare
|
||||
*
|
||||
@@ -103,8 +92,7 @@ public class NamedEntityObjectIdentity implements AclObjectIdentity {
|
||||
|
||||
NamedEntityObjectIdentity other = (NamedEntityObjectIdentity) arg0;
|
||||
|
||||
if (this.getId().equals(other.getId())
|
||||
&& this.getClassname().equals(other.getClassname())) {
|
||||
if (this.getId().equals(other.getId()) && this.getClassname().equals(other.getClassname())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SimpleAclEntry extends AbstractBasicAclEntry {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SimpleAclEntry.class);
|
||||
|
||||
@@ -39,18 +39,20 @@ public class SimpleAclEntry extends AbstractBasicAclEntry {
|
||||
public static final int DELETE = (int) Math.pow(2, 4);
|
||||
|
||||
// Combinations of base permissions we permit
|
||||
public static final int READ_WRITE_CREATE_DELETE = READ | WRITE | CREATE
|
||||
| DELETE;
|
||||
public static final int READ_WRITE_CREATE_DELETE = READ | WRITE | CREATE | DELETE;
|
||||
public static final int READ_WRITE_CREATE = READ | WRITE | CREATE;
|
||||
public static final int READ_WRITE = READ | WRITE;
|
||||
public static final int READ_WRITE_DELETE = READ | WRITE | DELETE;
|
||||
|
||||
// Array required by the abstract superclass via getValidPermissions()
|
||||
private static final int[] validPermissions = {NOTHING, ADMINISTRATION, READ, WRITE, CREATE, DELETE, READ_WRITE_CREATE_DELETE, READ_WRITE_CREATE, READ_WRITE, READ_WRITE_DELETE};
|
||||
private static final int[] validPermissions = {
|
||||
NOTHING, ADMINISTRATION, READ, WRITE, CREATE, DELETE, READ_WRITE_CREATE_DELETE, READ_WRITE_CREATE,
|
||||
READ_WRITE, READ_WRITE_DELETE
|
||||
};
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Allows {@link BasicAclDao} implementations to construct this object
|
||||
* using <code>newInstance()</code>.
|
||||
*
|
||||
@@ -62,13 +64,12 @@ public class SimpleAclEntry extends AbstractBasicAclEntry {
|
||||
super();
|
||||
}
|
||||
|
||||
public SimpleAclEntry(Object recipient,
|
||||
AclObjectIdentity aclObjectIdentity,
|
||||
public SimpleAclEntry(Object recipient, AclObjectIdentity aclObjectIdentity,
|
||||
AclObjectIdentity aclObjectParentIdentity, int mask) {
|
||||
super(recipient, aclObjectIdentity, aclObjectParentIdentity, mask);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public int[] getValidPermissions() {
|
||||
return validPermissions;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,36 +17,28 @@ package org.acegisecurity.acl.basic.cache;
|
||||
|
||||
import org.acegisecurity.acl.basic.BasicAclEntry;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Used by {@link EhCacheBasedAclEntryCache} to store the array of
|
||||
* <code>BasicAclEntry</code>s in the cache.
|
||||
*
|
||||
* <P>
|
||||
* This is necessary because caches store a single object per key, not an
|
||||
* array.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* This class uses value object semantics. ie: construction-based
|
||||
* initialisation without any setters for the properties.
|
||||
* </p>
|
||||
* Used by {@link EhCacheBasedAclEntryCache} to store the array of <code>BasicAclEntry</code>s in the cache.<P>This
|
||||
* is necessary because caches store a single object per key, not an array.</p>
|
||||
* <P>This class uses value object semantics. ie: construction-based initialisation without any setters for the
|
||||
* properties.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BasicAclEntryHolder implements Serializable {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private BasicAclEntry[] basicAclEntries;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs the <code>BasicAclEntryHolder</code>.
|
||||
*
|
||||
* @param aclEntries to cache (any <code>null</code>s will cause an
|
||||
@@ -68,7 +60,7 @@ public class BasicAclEntryHolder implements Serializable {
|
||||
this.basicAclEntries = aclEntries;
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public BasicAclEntry[] getBasicAclEntries() {
|
||||
return basicAclEntries;
|
||||
|
||||
@@ -40,17 +40,16 @@ import org.springframework.util.Assert;
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
|
||||
InitializingBean {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, InitializingBean {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(EhCacheBasedAclEntryCache.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Cache cache;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(cache, "cache mandatory");
|
||||
@@ -60,15 +59,13 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
|
||||
return cache;
|
||||
}
|
||||
|
||||
public BasicAclEntry[] getEntriesFromCache(
|
||||
AclObjectIdentity aclObjectIdentity) {
|
||||
public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity) {
|
||||
Element element = null;
|
||||
|
||||
try {
|
||||
element = cache.get(aclObjectIdentity);
|
||||
} catch (CacheException cacheException) {
|
||||
throw new DataRetrievalFailureException("Cache failure: "
|
||||
+ cacheException.getMessage());
|
||||
throw new DataRetrievalFailureException("Cache failure: " + cacheException.getMessage());
|
||||
}
|
||||
|
||||
// Return null if cache element has expired or not found
|
||||
@@ -81,8 +78,7 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Cache hit: " + (element != null) + "; object: "
|
||||
+ aclObjectIdentity);
|
||||
logger.debug("Cache hit: " + (element != null) + "; object: " + aclObjectIdentity);
|
||||
}
|
||||
|
||||
BasicAclEntryHolder holder = (BasicAclEntryHolder) element.getValue();
|
||||
@@ -92,8 +88,7 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
|
||||
|
||||
public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {
|
||||
BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry);
|
||||
Element element = new Element(basicAclEntry[0].getAclObjectIdentity(),
|
||||
holder);
|
||||
Element element = new Element(basicAclEntry[0].getAclObjectIdentity(), holder);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Cache put: " + element.getKey());
|
||||
|
||||
@@ -21,29 +21,23 @@ import org.acegisecurity.acl.basic.BasicAclEntryCache;
|
||||
|
||||
|
||||
/**
|
||||
* Does not perform any caching.
|
||||
*
|
||||
* <P>
|
||||
* <B>Do not use in production settings</B>, as ACL queries are likely to be
|
||||
* extensive.
|
||||
* </p>
|
||||
* Does not perform any caching.<P><B>Do not use in production settings</B>, as ACL queries are likely to be
|
||||
* extensive.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class NullAclEntryCache implements BasicAclEntryCache {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* As nothing ever stored in the cache, will always return
|
||||
* <code>null</code>.
|
||||
* As nothing ever stored in the cache, will always return <code>null</code>.
|
||||
*
|
||||
* @param aclObjectIdentity ignored
|
||||
*
|
||||
* @return always <code>null</code>
|
||||
*/
|
||||
public BasicAclEntry[] getEntriesFromCache(
|
||||
AclObjectIdentity aclObjectIdentity) {
|
||||
public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,56 +42,48 @@ import javax.sql.DataSource;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Retrieves ACL details from a JDBC location.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* A default database structure is assumed. This may be overridden by setting
|
||||
* the default query strings to use. If this does not provide enough
|
||||
* flexibility, another strategy would be to subclass this class and override
|
||||
* the {@link MappingSqlQuery} instance used, via the {@link
|
||||
* #initMappingSqlQueries()} extension point.
|
||||
* </p>
|
||||
* <p>Retrieves ACL details from a JDBC location.</p>
|
||||
* <p>A default database structure is assumed. This may be overridden by setting the default query strings to use.
|
||||
* If this does not provide enough flexibility, another strategy would be to subclass this class and override the
|
||||
* {@link MappingSqlQuery} instance used, via the {@link #initMappingSqlQueries()} extension point.</p>
|
||||
*/
|
||||
public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
public static final String RECIPIENT_USED_FOR_INHERITENCE_MARKER = "___INHERITENCE_MARKER_ONLY___";
|
||||
public static final String DEF_ACLS_BY_OBJECT_IDENTITY_QUERY = "SELECT RECIPIENT, MASK FROM acl_permission WHERE acl_object_identity = ?";
|
||||
public static final String DEF_OBJECT_PROPERTIES_QUERY = "SELECT CHILD.ID, CHILD.OBJECT_IDENTITY, CHILD.ACL_CLASS, PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY FROM acl_object_identity as CHILD LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id WHERE CHILD.object_identity = ?";
|
||||
private static final Log logger = LogFactory.getLog(JdbcDaoImpl.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected MappingSqlQuery aclsByObjectIdentity;
|
||||
protected MappingSqlQuery objectProperties;
|
||||
private String aclsByObjectIdentityQuery;
|
||||
private String objectPropertiesQuery;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public JdbcDaoImpl() {
|
||||
aclsByObjectIdentityQuery = DEF_ACLS_BY_OBJECT_IDENTITY_QUERY;
|
||||
objectPropertiesQuery = DEF_OBJECT_PROPERTIES_QUERY;
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Responsible for covering a <code>AclObjectIdentity</code> to a
|
||||
* <code>String</code> that can be located in the RDBMS.
|
||||
* Responsible for covering a <code>AclObjectIdentity</code> to a <code>String</code> that can be located
|
||||
* in the RDBMS.
|
||||
*
|
||||
* @param aclObjectIdentity to locate
|
||||
*
|
||||
* @return the object identity as a <code>String</code>
|
||||
*/
|
||||
protected String convertAclObjectIdentityToString(
|
||||
AclObjectIdentity aclObjectIdentity) {
|
||||
protected String convertAclObjectIdentityToString(AclObjectIdentity aclObjectIdentity) {
|
||||
// Ensure we can process this type of AclObjectIdentity
|
||||
Assert.isInstanceOf(NamedEntityObjectIdentity.class, aclObjectIdentity,
|
||||
"Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: "
|
||||
+ aclObjectIdentity + ")");
|
||||
"Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: " + aclObjectIdentity
|
||||
+ ")");
|
||||
|
||||
NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity;
|
||||
|
||||
@@ -100,37 +92,26 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an individual <code>BasicAclEntry</code> from the passed
|
||||
* <code>AclDetailsHolder</code>s.
|
||||
*
|
||||
* <P>
|
||||
* Guarantees to never return <code>null</code> (exceptions are thrown in
|
||||
* the event of any issues).
|
||||
* </p>
|
||||
* Constructs an individual <code>BasicAclEntry</code> from the passed <code>AclDetailsHolder</code>s.<P>Guarantees
|
||||
* to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
|
||||
*
|
||||
* @param propertiesInformation mandatory information about which instance
|
||||
* to create, the object identity, and the parent object identity
|
||||
* (<code>null</code> or empty <code>String</code>s prohibited for
|
||||
* @param propertiesInformation mandatory information about which instance to create, the object identity, and the
|
||||
* parent object identity (<code>null</code> or empty <code>String</code>s prohibited for
|
||||
* <code>aclClass</code> and <code>aclObjectIdentity</code>
|
||||
* @param aclInformation optional information about the individual ACL
|
||||
* record (if <code>null</code> only an "inheritence marker"
|
||||
* instance is returned which will include a recipient of {@link
|
||||
* #RECIPIENT_USED_FOR_INHERITENCE_MARKER} ; if not
|
||||
* <code>null</code>, it is prohibited to present <code>null</code>
|
||||
* or an empty <code>String</code> for <code>recipient</code>)
|
||||
* @param aclInformation optional information about the individual ACL record (if <code>null</code> only an
|
||||
* "inheritence marker" instance is returned which will include a recipient of {@link
|
||||
* #RECIPIENT_USED_FOR_INHERITENCE_MARKER} ; if not <code>null</code>, it is prohibited to present
|
||||
* <code>null</code> or an empty <code>String</code> for <code>recipient</code>)
|
||||
*
|
||||
* @return a fully populated instance suitable for use by external objects
|
||||
*
|
||||
* @throws IllegalArgumentException if the indicated ACL class could not be
|
||||
* created
|
||||
* @throws IllegalArgumentException if the indicated ACL class could not be created
|
||||
*/
|
||||
private BasicAclEntry createBasicAclEntry(
|
||||
AclDetailsHolder propertiesInformation, AclDetailsHolder aclInformation) {
|
||||
private BasicAclEntry createBasicAclEntry(AclDetailsHolder propertiesInformation, AclDetailsHolder aclInformation) {
|
||||
BasicAclEntry entry;
|
||||
|
||||
try {
|
||||
entry = (BasicAclEntry) propertiesInformation.getAclClass()
|
||||
.newInstance();
|
||||
entry = (BasicAclEntry) propertiesInformation.getAclClass().newInstance();
|
||||
} catch (InstantiationException ie) {
|
||||
throw new IllegalArgumentException(ie.getMessage());
|
||||
} catch (IllegalAccessException iae) {
|
||||
@@ -138,8 +119,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
}
|
||||
|
||||
entry.setAclObjectIdentity(propertiesInformation.getAclObjectIdentity());
|
||||
entry.setAclObjectParentIdentity(propertiesInformation
|
||||
.getAclObjectParentIdentity());
|
||||
entry.setAclObjectParentIdentity(propertiesInformation.getAclObjectParentIdentity());
|
||||
|
||||
if (aclInformation == null) {
|
||||
// this is an inheritence marker instance only
|
||||
@@ -155,30 +135,19 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ACLs associated with the requested
|
||||
* <code>AclObjectIdentity</code>.
|
||||
*
|
||||
* <P>
|
||||
* The {@link BasicAclEntry}s returned by this method will have
|
||||
* <code>String</code>-based recipients. This will not be a problem if you
|
||||
* are using the <code>GrantedAuthorityEffectiveAclsResolver</code>, which
|
||||
* is the default configured against <code>BasicAclProvider</code>.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* This method will only return ACLs for requests where the
|
||||
* <code>AclObjectIdentity</code> is of type {@link
|
||||
* NamedEntityObjectIdentity}. Of course, you can subclass or replace this
|
||||
* class and support your own custom <code>AclObjectIdentity</code> types.
|
||||
* </p>
|
||||
* Returns the ACLs associated with the requested <code>AclObjectIdentity</code>.<P>The {@link
|
||||
* BasicAclEntry}s returned by this method will have <code>String</code>-based recipients. This will not be a
|
||||
* problem if you are using the <code>GrantedAuthorityEffectiveAclsResolver</code>, which is the default
|
||||
* configured against <code>BasicAclProvider</code>.</p>
|
||||
* <P>This method will only return ACLs for requests where the <code>AclObjectIdentity</code> is of type
|
||||
* {@link NamedEntityObjectIdentity}. Of course, you can subclass or replace this class and support your own
|
||||
* custom <code>AclObjectIdentity</code> types.</p>
|
||||
*
|
||||
* @param aclObjectIdentity for which ACL information is required (cannot
|
||||
* be <code>null</code> and must be an instance of
|
||||
* <code>NamedEntityObjectIdentity</code>)
|
||||
* @param aclObjectIdentity for which ACL information is required (cannot be <code>null</code> and must be an
|
||||
* instance of <code>NamedEntityObjectIdentity</code>)
|
||||
*
|
||||
* @return the ACLs that apply (without any <code>null</code>s inside the
|
||||
* array), or <code>null</code> if not found or if an incompatible
|
||||
* <code>AclObjectIdentity</code> was requested
|
||||
* @return the ACLs that apply (without any <code>null</code>s inside the array), or <code>null</code> if not found
|
||||
* or if an incompatible <code>AclObjectIdentity</code> was requested
|
||||
*/
|
||||
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
|
||||
String aclObjectIdentityString;
|
||||
@@ -201,21 +170,18 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects.get(0);
|
||||
|
||||
// Lookup the object's ACLs from RDBMS (guaranteed no nulls)
|
||||
List acls = aclsByObjectIdentity.execute(propertiesInformation
|
||||
.getForeignKeyId());
|
||||
List acls = aclsByObjectIdentity.execute(propertiesInformation.getForeignKeyId());
|
||||
|
||||
if (acls.size() == 0) {
|
||||
// return merely an inheritence marker (as we know about the object but it has no related ACLs)
|
||||
return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation,
|
||||
null)};
|
||||
return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation, null)};
|
||||
} else {
|
||||
// return the individual ACL instances
|
||||
AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls.toArray(new AclDetailsHolder[] {});
|
||||
List toReturnAcls = new Vector();
|
||||
|
||||
for (int i = 0; i < aclHolders.length; i++) {
|
||||
toReturnAcls.add(createBasicAclEntry(propertiesInformation,
|
||||
aclHolders[i]));
|
||||
toReturnAcls.add(createBasicAclEntry(propertiesInformation, aclHolders[i]));
|
||||
}
|
||||
|
||||
return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {});
|
||||
@@ -239,26 +205,22 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension point to allow other MappingSqlQuery objects to be substituted
|
||||
* in a subclass
|
||||
* Extension point to allow other MappingSqlQuery objects to be substituted in a subclass
|
||||
*/
|
||||
protected void initMappingSqlQueries() {
|
||||
setAclsByObjectIdentity(new AclsByObjectIdentityMapping(getDataSource()));
|
||||
setObjectProperties(new ObjectPropertiesMapping(getDataSource()));
|
||||
}
|
||||
|
||||
public void setAclsByObjectIdentity(
|
||||
MappingSqlQuery aclsByObjectIdentityQuery) {
|
||||
public void setAclsByObjectIdentity(MappingSqlQuery aclsByObjectIdentityQuery) {
|
||||
this.aclsByObjectIdentity = aclsByObjectIdentityQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the default query string used to retrieve ACLs based on object
|
||||
* identity to be overriden, if default table or column names need to be
|
||||
* changed. The default query is {@link
|
||||
* #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure
|
||||
* that all returned columns are mapped back to the same column names as
|
||||
* in the default query.
|
||||
* Allows the default query string used to retrieve ACLs based on object identity to be overriden, if
|
||||
* default table or column names need to be changed. The default query is {@link
|
||||
* #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure that all returned columns are mapped
|
||||
* back to the same column names as in the default query.
|
||||
*
|
||||
* @param queryString The query string to set
|
||||
*/
|
||||
@@ -274,22 +236,14 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
objectPropertiesQuery = queryString;
|
||||
}
|
||||
|
||||
//~ Inner Classes ==========================================================
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
/**
|
||||
* Used to hold details of a domain object instance's properties, or an
|
||||
* individual ACL entry.
|
||||
*
|
||||
* <P>
|
||||
* Not all properties will be set. The actual properties set will depend on
|
||||
* which <code>MappingSqlQuery</code> creates the object.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* Does not enforce <code>null</code>s or empty <code>String</code>s as
|
||||
* this is performed by the <code>MappingSqlQuery</code> objects (or
|
||||
* preferably the backend RDBMS via schema constraints).
|
||||
* </p>
|
||||
* Used to hold details of a domain object instance's properties, or an individual ACL entry.<P>Not all
|
||||
* properties will be set. The actual properties set will depend on which <code>MappingSqlQuery</code> creates the
|
||||
* object.</p>
|
||||
* <P>Does not enforce <code>null</code>s or empty <code>String</code>s as this is performed by the
|
||||
* <code>MappingSqlQuery</code> objects (or preferably the backend RDBMS via schema constraints).</p>
|
||||
*/
|
||||
protected final class AclDetailsHolder {
|
||||
private AclObjectIdentity aclObjectIdentity;
|
||||
@@ -299,7 +253,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
private int mask;
|
||||
private long foreignKeyId;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Record details of an individual ACL entry (usually from the
|
||||
* ACL_PERMISSION table)
|
||||
*
|
||||
@@ -311,7 +265,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Record details of a domain object instance's properties (usually
|
||||
* from the ACL_OBJECT_IDENTITY table)
|
||||
*
|
||||
@@ -326,8 +280,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
* created for each individual ACL entry (or an inheritence
|
||||
* "holder" class if there are no ACL entries)
|
||||
*/
|
||||
public AclDetailsHolder(long foreignKeyId,
|
||||
AclObjectIdentity aclObjectIdentity,
|
||||
public AclDetailsHolder(long foreignKeyId, AclObjectIdentity aclObjectIdentity,
|
||||
AclObjectIdentity aclObjectParentIdentity, Class aclClass) {
|
||||
this.foreignKeyId = foreignKeyId;
|
||||
this.aclObjectIdentity = aclObjectIdentity;
|
||||
@@ -361,21 +314,11 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
}
|
||||
|
||||
/**
|
||||
* Query object to look up individual ACL entries.
|
||||
*
|
||||
* <P>
|
||||
* Returns the generic <code>AclDetailsHolder</code> object.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* Guarantees to never return <code>null</code> (exceptions are thrown in
|
||||
* the event of any issues).
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* The executed SQL requires the following information be made available
|
||||
* from the indicated placeholders: 1. RECIPIENT, 2. MASK.
|
||||
* </p>
|
||||
* Query object to look up individual ACL entries.<P>Returns the generic <code>AclDetailsHolder</code>
|
||||
* object.</p>
|
||||
* <P>Guarantees to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
|
||||
* <P>The executed SQL requires the following information be made available from the indicated
|
||||
* placeholders: 1. RECIPIENT, 2. MASK.</p>
|
||||
*/
|
||||
protected class AclsByObjectIdentityMapping extends MappingSqlQuery {
|
||||
protected AclsByObjectIdentityMapping(DataSource ds) {
|
||||
@@ -395,22 +338,11 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
}
|
||||
|
||||
/**
|
||||
* Query object to look up properties for an object identity.
|
||||
*
|
||||
* <P>
|
||||
* Returns the generic <code>AclDetailsHolder</code> object.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* Guarantees to never return <code>null</code> (exceptions are thrown in
|
||||
* the event of any issues).
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* The executed SQL requires the following information be made available
|
||||
* from the indicated placeholders: 1. ID, 2. OBJECT_IDENTITY, 3.
|
||||
* ACL_CLASS and 4. PARENT_OBJECT_IDENTITY.
|
||||
* </p>
|
||||
* Query object to look up properties for an object identity.<P>Returns the generic
|
||||
* <code>AclDetailsHolder</code> object.</p>
|
||||
* <P>Guarantees to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
|
||||
* <P>The executed SQL requires the following information be made available from the indicated
|
||||
* placeholders: 1. ID, 2. OBJECT_IDENTITY, 3. ACL_CLASS and 4. PARENT_OBJECT_IDENTITY.</p>
|
||||
*/
|
||||
protected class ObjectPropertiesMapping extends MappingSqlQuery {
|
||||
protected ObjectPropertiesMapping(DataSource ds) {
|
||||
@@ -440,8 +372,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
String parentObjectIdentity = rs.getString(4); // optional
|
||||
Assert.hasText(objectIdentity,
|
||||
"required DEF_OBJECT_PROPERTIES_QUERY value (objectIdentity) returned null or empty");
|
||||
Assert.hasText(aclClass,
|
||||
"required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty");
|
||||
Assert.hasText(aclClass, "required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty");
|
||||
|
||||
Class aclClazz;
|
||||
|
||||
@@ -451,8 +382,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||
throw new IllegalArgumentException(cnf.getMessage());
|
||||
}
|
||||
|
||||
return new AclDetailsHolder(id, buildIdentity(objectIdentity),
|
||||
buildIdentity(parentObjectIdentity), aclClazz);
|
||||
return new AclDetailsHolder(id, buildIdentity(objectIdentity), buildIdentity(parentObjectIdentity), aclClazz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,36 +47,20 @@ import javax.sql.DataSource;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Extension of the base {@link JdbcDaoImpl}, which implements {@link
|
||||
* BasicAclExtendedDao}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* A default database structure is assumed. This may be overridden by setting
|
||||
* the default query strings to use.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If you are using a cache with <code>BasicAclProvider</code>, you should
|
||||
* specify that cache via {@link #setBasicAclEntryCache(BasicAclEntryCache)}.
|
||||
* This will cause cache evictions (removals) to take place whenever a DAO
|
||||
* mutator method is called.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This implementation works with <code>String</code> based recipients and
|
||||
* {@link org.acegisecurity.acl.basic.NamedEntityObjectIdentity} only. The
|
||||
* latter can be changed by overriding {@link
|
||||
* #convertAclObjectIdentityToString(AclObjectIdentity)}.
|
||||
* </p>
|
||||
* <p>Extension of the base {@link JdbcDaoImpl}, which implements {@link BasicAclExtendedDao}.</p>
|
||||
* <p>A default database structure is assumed. This may be overridden by setting the default query strings to use.</p>
|
||||
* <p>If you are using a cache with <code>BasicAclProvider</code>, you should specify that cache via {@link
|
||||
* #setBasicAclEntryCache(BasicAclEntryCache)}. This will cause cache evictions (removals) to take place whenever a
|
||||
* DAO mutator method is called.</p>
|
||||
* <p>This implementation works with <code>String</code> based recipients and {@link
|
||||
* org.acegisecurity.acl.basic.NamedEntityObjectIdentity} only. The latter can be changed by overriding {@link
|
||||
* #convertAclObjectIdentityToString(AclObjectIdentity)}.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
implements BasicAclExtendedDao {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class JdbcExtendedDaoImpl extends JdbcDaoImpl implements BasicAclExtendedDao {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JdbcExtendedDaoImpl.class);
|
||||
public static final String DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT = "DELETE FROM acl_object_identity WHERE id = ?";
|
||||
@@ -86,7 +70,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
public static final String DEF_ACL_PERMISSION_UPDATE_STATEMENT = "UPDATE acl_permission SET mask = ? WHERE id = ?";
|
||||
public static final String DEF_LOOKUP_PERMISSION_ID_QUERY = "SELECT id FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AclObjectIdentityDelete aclObjectIdentityDelete;
|
||||
private AclObjectIdentityInsert aclObjectIdentityInsert;
|
||||
@@ -102,7 +86,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
private String aclPermissionUpdateStatement;
|
||||
private String lookupPermissionIdQuery;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public JdbcExtendedDaoImpl() {
|
||||
aclObjectIdentityDeleteStatement = DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT;
|
||||
@@ -113,22 +97,20 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
lookupPermissionIdQuery = DEF_LOOKUP_PERMISSION_ID_QUERY;
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void changeMask(AclObjectIdentity aclObjectIdentity,
|
||||
Object recipient, Integer newMask) throws DataAccessException {
|
||||
public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask)
|
||||
throws DataAccessException {
|
||||
basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity);
|
||||
|
||||
// Retrieve acl_object_identity record details
|
||||
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
|
||||
|
||||
// Retrieve applicable acl_permission.id
|
||||
long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(),
|
||||
recipient.toString());
|
||||
long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), recipient.toString());
|
||||
|
||||
if (permissionId == -1) {
|
||||
throw new DataRetrievalFailureException(
|
||||
"Could not locate existing acl_permission for aclObjectIdentity: "
|
||||
throw new DataRetrievalFailureException("Could not locate existing acl_permission for aclObjectIdentity: "
|
||||
+ aclObjectIdentity + ", recipient: " + recipient.toString());
|
||||
}
|
||||
|
||||
@@ -147,59 +129,48 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
}
|
||||
|
||||
// Retrieve acl_object_identity record details
|
||||
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(basicAclEntry
|
||||
.getAclObjectIdentity());
|
||||
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(basicAclEntry.getAclObjectIdentity());
|
||||
|
||||
// Ensure there isn't an existing record for this recipient
|
||||
long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(),
|
||||
basicAclEntry.getRecipient());
|
||||
long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), basicAclEntry.getRecipient());
|
||||
|
||||
if (permissionId != -1) {
|
||||
throw new DataIntegrityViolationException("Recipient '"
|
||||
+ basicAclEntry.getRecipient()
|
||||
+ "' already exists for aclObjectIdentity ID "
|
||||
+ aclDetailsHolder.getForeignKeyId() + " (permission ID " + ")");
|
||||
throw new DataIntegrityViolationException("Recipient '" + basicAclEntry.getRecipient()
|
||||
+ "' already exists for aclObjectIdentity ID " + aclDetailsHolder.getForeignKeyId()
|
||||
+ " (permission ID " + ")");
|
||||
}
|
||||
|
||||
// Create acl_permission
|
||||
aclPermissionInsert.insert(new Long(aclDetailsHolder.getForeignKeyId()),
|
||||
basicAclEntry.getRecipient().toString(),
|
||||
new Integer(basicAclEntry.getMask()));
|
||||
basicAclEntry.getRecipient().toString(), new Integer(basicAclEntry.getMask()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that creates an acl_object_identity record if
|
||||
* required.
|
||||
* Convenience method that creates an acl_object_identity record if required.
|
||||
*
|
||||
* @param basicAclEntry containing the <code>AclObjectIdentity</code> to
|
||||
* create
|
||||
* @param basicAclEntry containing the <code>AclObjectIdentity</code> to create
|
||||
*
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
private void createAclObjectIdentityIfRequired(BasicAclEntry basicAclEntry)
|
||||
throws DataAccessException {
|
||||
basicAclEntryCache.removeEntriesFromCache(basicAclEntry
|
||||
.getAclObjectIdentity());
|
||||
basicAclEntryCache.removeEntriesFromCache(basicAclEntry.getAclObjectIdentity());
|
||||
|
||||
String aclObjectIdentityString = convertAclObjectIdentityToString(basicAclEntry
|
||||
.getAclObjectIdentity());
|
||||
String aclObjectIdentityString = convertAclObjectIdentityToString(basicAclEntry.getAclObjectIdentity());
|
||||
|
||||
// Lookup the object's main properties from the RDBMS (guaranteed no nulls)
|
||||
List objects = objectProperties.execute(aclObjectIdentityString);
|
||||
|
||||
if (objects.size() == 0) {
|
||||
if (basicAclEntry.getAclObjectParentIdentity() != null) {
|
||||
AclDetailsHolder parentDetails = lookupAclDetailsHolder(basicAclEntry
|
||||
.getAclObjectParentIdentity());
|
||||
AclDetailsHolder parentDetails = lookupAclDetailsHolder(basicAclEntry.getAclObjectParentIdentity());
|
||||
|
||||
// Must create the acl_object_identity record
|
||||
aclObjectIdentityInsert.insert(aclObjectIdentityString,
|
||||
new Long(parentDetails.getForeignKeyId()),
|
||||
aclObjectIdentityInsert.insert(aclObjectIdentityString, new Long(parentDetails.getForeignKeyId()),
|
||||
basicAclEntry.getClass().getName());
|
||||
} else {
|
||||
// Must create the acl_object_identity record
|
||||
aclObjectIdentityInsert.insert(aclObjectIdentityString, null,
|
||||
basicAclEntry.getClass().getName());
|
||||
aclObjectIdentityInsert.insert(aclObjectIdentityString, null, basicAclEntry.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,8 +183,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
|
||||
|
||||
// Retrieve all acl_permissions applying to this acl_object_identity
|
||||
Iterator acls = aclsByObjectIdentity.execute(aclDetailsHolder
|
||||
.getForeignKeyId()).iterator();
|
||||
Iterator acls = aclsByObjectIdentity.execute(aclDetailsHolder.getForeignKeyId()).iterator();
|
||||
|
||||
// Delete all existing acl_permissions applying to this acl_object_identity
|
||||
while (acls.hasNext()) {
|
||||
@@ -222,8 +192,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
}
|
||||
|
||||
// Delete acl_object_identity
|
||||
aclObjectIdentityDelete.delete(new Long(
|
||||
aclDetailsHolder.getForeignKeyId()));
|
||||
aclObjectIdentityDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()));
|
||||
}
|
||||
|
||||
public void delete(AclObjectIdentity aclObjectIdentity, Object recipient)
|
||||
@@ -234,8 +203,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
|
||||
|
||||
// Delete acl_permission
|
||||
aclPermissionDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()),
|
||||
recipient.toString());
|
||||
aclPermissionDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()), recipient.toString());
|
||||
}
|
||||
|
||||
public AclObjectIdentityDelete getAclObjectIdentityDelete() {
|
||||
@@ -309,8 +277,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
*
|
||||
* @throws DataRetrievalFailureException if record could not be found
|
||||
*/
|
||||
private AclDetailsHolder lookupAclDetailsHolder(
|
||||
AclObjectIdentity aclObjectIdentity)
|
||||
private AclDetailsHolder lookupAclDetailsHolder(AclObjectIdentity aclObjectIdentity)
|
||||
throws DataRetrievalFailureException {
|
||||
String aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
|
||||
|
||||
@@ -318,8 +285,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
List objects = objectProperties.execute(aclObjectIdentityString);
|
||||
|
||||
if (objects.size() == 0) {
|
||||
throw new DataRetrievalFailureException(
|
||||
"aclObjectIdentity not found: " + aclObjectIdentityString);
|
||||
throw new DataRetrievalFailureException("aclObjectIdentity not found: " + aclObjectIdentityString);
|
||||
}
|
||||
|
||||
// Should only be one record
|
||||
@@ -327,8 +293,8 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to lookup the acl_permission applying to a given
|
||||
* acl_object_identity.id and acl_permission.recipient.
|
||||
* Convenience method to lookup the acl_permission applying to a given acl_object_identity.id and
|
||||
* acl_permission.recipient.
|
||||
*
|
||||
* @param aclObjectIdentityId to locate
|
||||
* @param recipient to locate
|
||||
@@ -339,8 +305,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
*/
|
||||
private long lookupPermissionId(long aclObjectIdentityId, Object recipient)
|
||||
throws DataAccessException {
|
||||
List list = lookupPermissionIdMapping.execute(new Object[] {new Long(
|
||||
aclObjectIdentityId), recipient});
|
||||
List list = lookupPermissionIdMapping.execute(new Object[] {new Long(aclObjectIdentityId), recipient});
|
||||
|
||||
if (list.size() == 0) {
|
||||
return -1;
|
||||
@@ -349,23 +314,19 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
return ((Long) list.get(0)).longValue();
|
||||
}
|
||||
|
||||
public void setAclObjectIdentityDelete(
|
||||
AclObjectIdentityDelete aclObjectIdentityDelete) {
|
||||
public void setAclObjectIdentityDelete(AclObjectIdentityDelete aclObjectIdentityDelete) {
|
||||
this.aclObjectIdentityDelete = aclObjectIdentityDelete;
|
||||
}
|
||||
|
||||
public void setAclObjectIdentityDeleteStatement(
|
||||
String aclObjectIdentityDeleteStatement) {
|
||||
public void setAclObjectIdentityDeleteStatement(String aclObjectIdentityDeleteStatement) {
|
||||
this.aclObjectIdentityDeleteStatement = aclObjectIdentityDeleteStatement;
|
||||
}
|
||||
|
||||
public void setAclObjectIdentityInsert(
|
||||
AclObjectIdentityInsert aclObjectIdentityInsert) {
|
||||
public void setAclObjectIdentityInsert(AclObjectIdentityInsert aclObjectIdentityInsert) {
|
||||
this.aclObjectIdentityInsert = aclObjectIdentityInsert;
|
||||
}
|
||||
|
||||
public void setAclObjectIdentityInsertStatement(
|
||||
String aclObjectIdentityInsertStatement) {
|
||||
public void setAclObjectIdentityInsertStatement(String aclObjectIdentityInsertStatement) {
|
||||
this.aclObjectIdentityInsertStatement = aclObjectIdentityInsertStatement;
|
||||
}
|
||||
|
||||
@@ -373,8 +334,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
this.aclPermissionDelete = aclPermissionDelete;
|
||||
}
|
||||
|
||||
public void setAclPermissionDeleteStatement(
|
||||
String aclPermissionDeleteStatement) {
|
||||
public void setAclPermissionDeleteStatement(String aclPermissionDeleteStatement) {
|
||||
this.aclPermissionDeleteStatement = aclPermissionDeleteStatement;
|
||||
}
|
||||
|
||||
@@ -382,8 +342,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
this.aclPermissionInsert = aclPermissionInsert;
|
||||
}
|
||||
|
||||
public void setAclPermissionInsertStatement(
|
||||
String aclPermissionInsertStatement) {
|
||||
public void setAclPermissionInsertStatement(String aclPermissionInsertStatement) {
|
||||
this.aclPermissionInsertStatement = aclPermissionInsertStatement;
|
||||
}
|
||||
|
||||
@@ -391,8 +350,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
this.aclPermissionUpdate = aclPermissionUpdate;
|
||||
}
|
||||
|
||||
public void setAclPermissionUpdateStatement(
|
||||
String aclPermissionUpdateStatement) {
|
||||
public void setAclPermissionUpdateStatement(String aclPermissionUpdateStatement) {
|
||||
this.aclPermissionUpdateStatement = aclPermissionUpdateStatement;
|
||||
}
|
||||
|
||||
@@ -401,8 +359,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
this.basicAclEntryCache = basicAclEntryCache;
|
||||
}
|
||||
|
||||
public void setLookupPermissionIdMapping(
|
||||
MappingSqlQuery lookupPermissionIdMapping) {
|
||||
public void setLookupPermissionIdMapping(MappingSqlQuery lookupPermissionIdMapping) {
|
||||
this.lookupPermissionIdMapping = lookupPermissionIdMapping;
|
||||
}
|
||||
|
||||
@@ -410,7 +367,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
this.lookupPermissionIdQuery = lookupPermissionIdQuery;
|
||||
}
|
||||
|
||||
//~ Inner Classes ==========================================================
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
protected class AclObjectIdentityDelete extends SqlUpdate {
|
||||
protected AclObjectIdentityDelete(DataSource ds) {
|
||||
@@ -419,8 +376,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
compile();
|
||||
}
|
||||
|
||||
protected void delete(Long aclObjectIdentity)
|
||||
throws DataAccessException {
|
||||
protected void delete(Long aclObjectIdentity) throws DataAccessException {
|
||||
super.update(aclObjectIdentity.intValue());
|
||||
}
|
||||
}
|
||||
@@ -434,8 +390,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
compile();
|
||||
}
|
||||
|
||||
protected void insert(String objectIdentity,
|
||||
Long parentAclObjectIdentity, String aclClass)
|
||||
protected void insert(String objectIdentity, Long parentAclObjectIdentity, String aclClass)
|
||||
throws DataAccessException {
|
||||
Object[] objs = new Object[] {objectIdentity, parentAclObjectIdentity, aclClass};
|
||||
super.update(objs);
|
||||
@@ -465,8 +420,8 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
|
||||
compile();
|
||||
}
|
||||
|
||||
protected void insert(Long aclObjectIdentity, String recipient,
|
||||
Integer mask) throws DataAccessException {
|
||||
protected void insert(Long aclObjectIdentity, String recipient, Integer mask)
|
||||
throws DataAccessException {
|
||||
Object[] objs = new Object[] {aclObjectIdentity, recipient, mask};
|
||||
super.update(objs);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.acegisecurity.adapters;
|
||||
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
|
||||
import org.acegisecurity.providers.AbstractAuthenticationToken;
|
||||
|
||||
|
||||
@@ -25,19 +26,18 @@ import org.acegisecurity.providers.AbstractAuthenticationToken;
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractAdapterAuthenticationToken
|
||||
extends AbstractAuthenticationToken implements AuthByAdapter {
|
||||
//~ Instance fields ========================================================
|
||||
public abstract class AbstractAdapterAuthenticationToken extends AbstractAuthenticationToken implements AuthByAdapter {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private int keyHash;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
protected AbstractAdapterAuthenticationToken() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* The only way an <code>AbstractAdapterAuthentication</code> should be
|
||||
* constructed.
|
||||
*
|
||||
@@ -45,62 +45,12 @@ public abstract class AbstractAdapterAuthenticationToken
|
||||
* #getKeyHash()}
|
||||
* @param authorities the authorities granted to this principal
|
||||
*/
|
||||
protected AbstractAdapterAuthenticationToken(String key,
|
||||
GrantedAuthority[] authorities) {
|
||||
protected AbstractAdapterAuthenticationToken(String key, GrantedAuthority[] authorities) {
|
||||
super(authorities);
|
||||
this.keyHash = key.hashCode();
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
/**
|
||||
* Setting is ignored. Always considered authenticated.
|
||||
*
|
||||
* @param ignored DOCUMENT ME!
|
||||
*/
|
||||
public void setAuthenticated(boolean ignored) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns <code>true</code>.
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
public boolean isAuthenticated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getKeyHash() {
|
||||
return this.keyHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates the granted authorities and indicates whether or not the
|
||||
* specified role is held.
|
||||
*
|
||||
* <p>
|
||||
* Comparison is based on the <code>String</code> returned by {@link
|
||||
* GrantedAuthority#getAuthority}.
|
||||
* </p>
|
||||
*
|
||||
* @param role the role being searched for in this object's granted
|
||||
* authorities list
|
||||
*
|
||||
* @return <code>true</code> if the granted authority is held, or
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isUserInRole(String role) {
|
||||
GrantedAuthority[] authorities = super.getAuthorities();
|
||||
|
||||
for (int i = 0; i < authorities.length; i++) {
|
||||
if (role.equals(authorities[i].getAuthority())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof AbstractAdapterAuthenticationToken) {
|
||||
@@ -115,4 +65,46 @@ public abstract class AbstractAdapterAuthenticationToken
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getKeyHash() {
|
||||
return this.keyHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns <code>true</code>.
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
public boolean isAuthenticated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates the granted authorities and indicates whether or not the specified role is held.<p>Comparison
|
||||
* is based on the <code>String</code> returned by {@link GrantedAuthority#getAuthority}.</p>
|
||||
*
|
||||
* @param role the role being searched for in this object's granted authorities list
|
||||
*
|
||||
* @return <code>true</code> if the granted authority is held, or <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isUserInRole(String role) {
|
||||
GrantedAuthority[] authorities = super.getAuthorities();
|
||||
|
||||
for (int i = 0; i < authorities.length; i++) {
|
||||
if (role.equals(authorities[i].getAuthority())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting is ignored. Always considered authenticated.
|
||||
*
|
||||
* @param ignored DOCUMENT ME!
|
||||
*/
|
||||
public void setAuthenticated(boolean ignored) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,13 +32,12 @@ import org.acegisecurity.Authentication;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AuthByAdapter extends Authentication {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Returns the hash code of the key that was passed to the constructor of
|
||||
* the <code>AuthByAdapter</code> implementation. The implementation
|
||||
* should convert the value to a hash code at construction time, rather
|
||||
* than storing the key itself.
|
||||
* Returns the hash code of the key that was passed to the constructor of the <code>AuthByAdapter</code>
|
||||
* implementation. The implementation should convert the value to a hash code at construction time, rather than
|
||||
* storing the key itself.
|
||||
*
|
||||
* @return the hash code of the key used when the object was created.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,32 +32,22 @@ import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* An {@link AuthenticationProvider} implementation that can authenticate an
|
||||
* {@link AuthByAdapter}.
|
||||
*
|
||||
* <P>
|
||||
* Configured in the bean context with a key that should match the key used by
|
||||
* adapters to generate <code>AuthByAdapter</code> instances. It treats as
|
||||
* valid any such instance presenting a hash code that matches the
|
||||
* <code>AuthByAdapterProvider</code>-configured key.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* If the key does not match, a <code>BadCredentialsException</code> is thrown.
|
||||
* </p>
|
||||
* An {@link AuthenticationProvider} implementation that can authenticate an {@link AuthByAdapter}.<P>Configured in
|
||||
* the bean context with a key that should match the key used by adapters to generate <code>AuthByAdapter</code>
|
||||
* instances. It treats as valid any such instance presenting a hash code that matches the
|
||||
* <code>AuthByAdapterProvider</code>-configured key.</p>
|
||||
* <P>If the key does not match, a <code>BadCredentialsException</code> is thrown.</p>
|
||||
*/
|
||||
public class AuthByAdapterProvider implements InitializingBean,
|
||||
AuthenticationProvider, MessageSourceAware {
|
||||
//~ Instance fields ========================================================
|
||||
public class AuthByAdapterProvider implements InitializingBean, AuthenticationProvider, MessageSourceAware {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
|
||||
private String key;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(key,
|
||||
"A Key is required and should match that configured for the adapters");
|
||||
Assert.notNull(key, "A Key is required and should match that configured for the adapters");
|
||||
Assert.notNull(messages, "A message source must be set");
|
||||
}
|
||||
|
||||
@@ -68,8 +58,7 @@ public class AuthByAdapterProvider implements InitializingBean,
|
||||
if (token.getKeyHash() == key.hashCode()) {
|
||||
return authentication;
|
||||
} else {
|
||||
throw new BadCredentialsException(messages.getMessage(
|
||||
"AuthByAdapterProvider.incorrectKey",
|
||||
throw new BadCredentialsException(messages.getMessage("AuthByAdapterProvider.incorrectKey",
|
||||
"The presented AuthByAdapter implementation does not contain the expected key"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.acegisecurity.adapters;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -35,63 +36,47 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Populates <code>SecurityContext</code> with the <code>Authentication</code>
|
||||
* obtained from the container's
|
||||
* <code>HttpServletRequest.getUserPrincipal()</code>.
|
||||
*
|
||||
* <p>
|
||||
* Use this filter with container adapters only.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This filter <b>never</b> preserves the <code>Authentication</code> on the
|
||||
* <code>SecurityContext</code> - it is replaced every request.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* See {@link org.acegisecurity.context.HttpSessionContextIntegrationFilter}
|
||||
* for further information.
|
||||
* </p>
|
||||
* Populates <code>SecurityContext</code> with the <code>Authentication</code> obtained from the container's
|
||||
* <code>HttpServletRequest.getUserPrincipal()</code>.<p>Use this filter with container adapters only.</p>
|
||||
* <p>This filter <b>never</b> preserves the <code>Authentication</code> on the <code>SecurityContext</code> - it
|
||||
* is replaced every request.</p>
|
||||
* <p>See {@link org.acegisecurity.context.HttpSessionContextIntegrationFilter} for further information.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class HttpRequestIntegrationFilter implements Filter {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(HttpRequestIntegrationFilter.class);
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Does nothing. We use IoC container lifecycle services instead.
|
||||
*/
|
||||
public void destroy() {}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
if (request instanceof HttpServletRequest) {
|
||||
Principal principal = ((HttpServletRequest) request)
|
||||
.getUserPrincipal();
|
||||
Principal principal = ((HttpServletRequest) request).getUserPrincipal();
|
||||
|
||||
if ((principal != null) && principal instanceof Authentication) {
|
||||
SecurityContextHolder.getContext().setAuthentication((Authentication) principal);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"SecurityContextHolder updated with Authentication from container: '"
|
||||
+ principal + "'");
|
||||
logger.debug("SecurityContextHolder updated with Authentication from container: '" + principal
|
||||
+ "'");
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"SecurityContextHolder not set with new Authentication as Principal was: '"
|
||||
logger.debug("SecurityContextHolder not set with new Authentication as Principal was: '"
|
||||
+ principal + "'");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Only HttpServletRequest is acceptable");
|
||||
throw new IllegalArgumentException("Only HttpServletRequest is acceptable");
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,31 +21,29 @@ import java.security.Principal;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link Principal} compatible {@link org.acegisecurity.Authentication}
|
||||
* object.
|
||||
* A {@link Principal} compatible {@link org.acegisecurity.Authentication} object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class PrincipalAcegiUserToken extends AbstractAdapterAuthenticationToken
|
||||
implements Principal {
|
||||
//~ Instance fields ========================================================
|
||||
public class PrincipalAcegiUserToken extends AbstractAdapterAuthenticationToken implements Principal {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Object principal;
|
||||
private String password;
|
||||
private String username;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public PrincipalAcegiUserToken(String key, String username,
|
||||
String password, GrantedAuthority[] authorities, Object principal) {
|
||||
public PrincipalAcegiUserToken(String key, String username, String password, GrantedAuthority[] authorities,
|
||||
Object principal) {
|
||||
super(key, authorities);
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Object getCredentials() {
|
||||
return this.password;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,36 +29,28 @@ import org.acegisecurity.ConfigAttributeDefinition;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AfterInvocationProvider {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Object decide(Authentication authentication, Object object,
|
||||
ConfigAttributeDefinition config, Object returnedObject)
|
||||
throws AccessDeniedException;
|
||||
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
|
||||
Object returnedObject) throws AccessDeniedException;
|
||||
|
||||
/**
|
||||
* Indicates whether this <code>AfterInvocationProvider</code> is able to
|
||||
* participate in a decision involving the passed
|
||||
* <code>ConfigAttribute</code>.
|
||||
*
|
||||
* <p>
|
||||
* This allows the <code>AbstractSecurityInterceptor</code> to check every
|
||||
* configuration attribute can be consumed by the configured
|
||||
* <code>AccessDecisionManager</code> and/or <code>RunAsManager</code>
|
||||
* and/or <code>AccessDecisionManager</code>.
|
||||
* </p>
|
||||
* Indicates whether this <code>AfterInvocationProvider</code> is able to participate in a decision
|
||||
* involving the passed <code>ConfigAttribute</code>.<p>This allows the
|
||||
* <code>AbstractSecurityInterceptor</code> to check every configuration attribute can be consumed by the
|
||||
* configured <code>AccessDecisionManager</code> and/or <code>RunAsManager</code> and/or
|
||||
* <code>AccessDecisionManager</code>.</p>
|
||||
*
|
||||
* @param attribute a configuration attribute that has been configured
|
||||
* against the <code>AbstractSecurityInterceptor</code>
|
||||
* @param attribute a configuration attribute that has been configured against the
|
||||
* <code>AbstractSecurityInterceptor</code>
|
||||
*
|
||||
* @return true if this <code>AfterInvocationProvider</code> can support
|
||||
* the passed configuration attribute
|
||||
* @return true if this <code>AfterInvocationProvider</code> can support the passed configuration attribute
|
||||
*/
|
||||
public boolean supports(ConfigAttribute attribute);
|
||||
|
||||
/**
|
||||
* Indicates whether the <code>AfterInvocationProvider</code> is able to
|
||||
* provide "after invocation" processing for the indicated secured object
|
||||
* type.
|
||||
* Indicates whether the <code>AfterInvocationProvider</code> is able to provide "after invocation"
|
||||
* processing for the indicated secured object type.
|
||||
*
|
||||
* @param clazz the class of secure object that is being queried
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,38 +31,55 @@ import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Provider-based implementation of {@link AfterInvocationManager}.
|
||||
*
|
||||
* <p>
|
||||
* Handles configuration of a bean context defined list of {@link
|
||||
* AfterInvocationProvider}s.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Every <code>AfterInvocationProvider</code> will be polled when the {@link
|
||||
* #decide(Authentication, Object, ConfigAttributeDefinition, Object)} method
|
||||
* is called. The <code>Object</code> returned from each provider will be
|
||||
* presented to the successive provider for processing. This means each
|
||||
* provider <b>must</b> ensure they return the <code>Object</code>, even if
|
||||
* they are not interested in the "after invocation" decision (perhaps as the
|
||||
* secure object invocation did not include a configuration attribute a given
|
||||
* provider is configured to respond to).
|
||||
* </p>
|
||||
* Provider-based implementation of {@link AfterInvocationManager}.<p>Handles configuration of a bean context
|
||||
* defined list of {@link AfterInvocationProvider}s.</p>
|
||||
* <p>Every <code>AfterInvocationProvider</code> will be polled when the {@link #decide(Authentication, Object,
|
||||
* ConfigAttributeDefinition, Object)} method is called. The <code>Object</code> returned from each provider will be
|
||||
* presented to the successive provider for processing. This means each provider <b>must</b> ensure they return the
|
||||
* <code>Object</code>, even if they are not interested in the "after invocation" decision (perhaps as the secure
|
||||
* object invocation did not include a configuration attribute a given provider is configured to respond to).</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AfterInvocationProviderManager implements AfterInvocationManager,
|
||||
InitializingBean {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class AfterInvocationProviderManager implements AfterInvocationManager, InitializingBean {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(AfterInvocationProviderManager.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private List providers;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
checkIfValidList(this.providers);
|
||||
}
|
||||
|
||||
private void checkIfValidList(List listToCheck) {
|
||||
if ((listToCheck == null) || (listToCheck.size() == 0)) {
|
||||
throw new IllegalArgumentException("A list of AfterInvocationProviders is required");
|
||||
}
|
||||
}
|
||||
|
||||
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
|
||||
Object returnedObject) throws AccessDeniedException {
|
||||
Iterator iter = this.providers.iterator();
|
||||
|
||||
Object result = returnedObject;
|
||||
|
||||
while (iter.hasNext()) {
|
||||
AfterInvocationProvider provider = (AfterInvocationProvider) iter.next();
|
||||
result = provider.decide(authentication, object, config, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public List getProviders() {
|
||||
return this.providers;
|
||||
}
|
||||
|
||||
public void setProviders(List newList) {
|
||||
checkIfValidList(newList);
|
||||
@@ -77,8 +94,7 @@ public class AfterInvocationProviderManager implements AfterInvocationManager,
|
||||
|
||||
AfterInvocationProvider attemptToCast = (AfterInvocationProvider) currentObject;
|
||||
} catch (ClassCastException cce) {
|
||||
throw new IllegalArgumentException("AfterInvocationProvider "
|
||||
+ currentObject.getClass().getName()
|
||||
throw new IllegalArgumentException("AfterInvocationProvider " + currentObject.getClass().getName()
|
||||
+ " must implement AfterInvocationProvider");
|
||||
}
|
||||
}
|
||||
@@ -86,36 +102,11 @@ public class AfterInvocationProviderManager implements AfterInvocationManager,
|
||||
this.providers = newList;
|
||||
}
|
||||
|
||||
public List getProviders() {
|
||||
return this.providers;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
checkIfValidList(this.providers);
|
||||
}
|
||||
|
||||
public Object decide(Authentication authentication, Object object,
|
||||
ConfigAttributeDefinition config, Object returnedObject)
|
||||
throws AccessDeniedException {
|
||||
Iterator iter = this.providers.iterator();
|
||||
|
||||
Object result = returnedObject;
|
||||
|
||||
while (iter.hasNext()) {
|
||||
AfterInvocationProvider provider = (AfterInvocationProvider) iter
|
||||
.next();
|
||||
result = provider.decide(authentication, object, config, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
Iterator iter = this.providers.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
AfterInvocationProvider provider = (AfterInvocationProvider) iter
|
||||
.next();
|
||||
AfterInvocationProvider provider = (AfterInvocationProvider) iter.next();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Evaluating " + attribute + " against " + provider);
|
||||
@@ -130,27 +121,19 @@ public class AfterInvocationProviderManager implements AfterInvocationManager,
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through all <code>AfterInvocationProvider</code>s and ensures
|
||||
* each can support the presented class.
|
||||
*
|
||||
* <p>
|
||||
* If one or more providers cannot support the presented class,
|
||||
* <code>false</code> is returned.
|
||||
* </p>
|
||||
* Iterates through all <code>AfterInvocationProvider</code>s and ensures each can support the presented
|
||||
* class.<p>If one or more providers cannot support the presented class, <code>false</code> is returned.</p>
|
||||
*
|
||||
* @param clazz the secure object class being queries
|
||||
*
|
||||
* @return if the <code>AfterInvocationProviderManager</code> can support
|
||||
* the secure object class, which requires every one of its
|
||||
* <code>AfterInvocationProvider</code>s to support the secure
|
||||
* object class
|
||||
* @return if the <code>AfterInvocationProviderManager</code> can support the secure object class, which requires
|
||||
* every one of its <code>AfterInvocationProvider</code>s to support the secure object class
|
||||
*/
|
||||
public boolean supports(Class clazz) {
|
||||
Iterator iter = this.providers.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
AfterInvocationProvider provider = (AfterInvocationProvider) iter
|
||||
.next();
|
||||
AfterInvocationProvider provider = (AfterInvocationProvider) iter.next();
|
||||
|
||||
if (!provider.supports(clazz)) {
|
||||
return false;
|
||||
@@ -159,11 +142,4 @@ public class AfterInvocationProviderManager implements AfterInvocationManager,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void checkIfValidList(List listToCheck) {
|
||||
if ((listToCheck == null) || (listToCheck.size() == 0)) {
|
||||
throw new IllegalArgumentException(
|
||||
"A list of AfterInvocationProviders is required");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthorizationServiceException;
|
||||
import org.acegisecurity.ConfigAttribute;
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
|
||||
import org.acegisecurity.acl.AclEntry;
|
||||
import org.acegisecurity.acl.AclManager;
|
||||
import org.acegisecurity.acl.basic.BasicAclEntry;
|
||||
@@ -42,125 +43,61 @@ import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Given a <code>Collection</code> of domain object instances returned from a
|
||||
* secure object invocation, remove any <code>Collection</code> elements the
|
||||
* principal does not have appropriate permission to access as defined by the
|
||||
* {@link AclManager}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The <code>AclManager</code> is used to retrieve the access control list
|
||||
* (ACL) permissions associated with each <code>Collection</code> domain
|
||||
* object instance element for the current <code>Authentication</code> object.
|
||||
* This class is designed to process {@link AclEntry}s that are subclasses of
|
||||
* {@link org.acegisecurity.acl.basic.BasicAclEntry} only.
|
||||
* Generally these are obtained by using the {@link
|
||||
* org.acegisecurity.acl.basic.BasicAclProvider}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This after invocation provider will fire if any {@link
|
||||
* ConfigAttribute#getAttribute()} matches the {@link
|
||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the
|
||||
* <code>AclManager</code> and ensure the principal is {@link
|
||||
* org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for
|
||||
* at least one of the {@link #requirePermission}s for each
|
||||
* <code>Collection</code> element. If the principal does not have at least
|
||||
* one of the permissions, that element will not be included in the returned
|
||||
* <code>Collection</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Often users will setup a <code>BasicAclEntryAfterInvocationProvider</code>
|
||||
* with a {@link #processConfigAttribute} of
|
||||
* <code>AFTER_ACL_COLLECTION_READ</code> and a {@link #requirePermission} of
|
||||
* <code>SimpleAclEntry.READ</code>. These are also the defaults.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The <code>AclManager</code> is allowed to return any implementations of
|
||||
* <code>AclEntry</code> it wishes. However, this provider will only be able
|
||||
* to validate against <code>BasicAclEntry</code>s, and thus a
|
||||
* <code>Collection</code> element will be filtered from the resulting
|
||||
* <code>Collection</code> if no <code>AclEntry</code> is of type
|
||||
* <code>BasicAclEntry</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If the provided <code>returnObject</code> is <code>null</code>, a
|
||||
* <code>null</code><code>Collection</code> will be returned. If the provided
|
||||
* <code>returnObject</code> is not a <code>Collection</code>, an {@link
|
||||
* AuthorizationServiceException} will be thrown.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* All comparisons and prefixes are case sensitive.
|
||||
* </p>
|
||||
* <p>Given a <code>Collection</code> of domain object instances returned from a secure object invocation, remove
|
||||
* any <code>Collection</code> elements the principal does not have appropriate permission to access as defined by the
|
||||
* {@link AclManager}.</p>
|
||||
* <p>The <code>AclManager</code> is used to retrieve the access control list (ACL) permissions associated with
|
||||
* each <code>Collection</code> domain object instance element for the current <code>Authentication</code> object.
|
||||
* This class is designed to process {@link AclEntry}s that are subclasses of {@link
|
||||
* org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are obtained by using the {@link
|
||||
* org.acegisecurity.acl.basic.BasicAclProvider}.</p>
|
||||
* <p>This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
|
||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the <code>AclManager</code> and ensure the
|
||||
* principal is {@link org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link
|
||||
* #requirePermission}s for each <code>Collection</code> element. If the principal does not have at least one of the
|
||||
* permissions, that element will not be included in the returned <code>Collection</code>.</p>
|
||||
* <p>Often users will setup a <code>BasicAclEntryAfterInvocationProvider</code> with a {@link
|
||||
* #processConfigAttribute} of <code>AFTER_ACL_COLLECTION_READ</code> and a {@link #requirePermission} of
|
||||
* <code>SimpleAclEntry.READ</code>. These are also the defaults.</p>
|
||||
* <p>The <code>AclManager</code> is allowed to return any implementations of <code>AclEntry</code> it wishes.
|
||||
* However, this provider will only be able to validate against <code>BasicAclEntry</code>s, and thus a
|
||||
* <code>Collection</code> element will be filtered from the resulting <code>Collection</code> if no
|
||||
* <code>AclEntry</code> is of type <code>BasicAclEntry</code>.</p>
|
||||
* <p>If the provided <code>returnObject</code> is <code>null</code>, a <code>null</code><code>Collection</code>
|
||||
* will be returned. If the provided <code>returnObject</code> is not a <code>Collection</code>, an {@link
|
||||
* AuthorizationServiceException} will be thrown.</p>
|
||||
* <p>All comparisons and prefixes are case sensitive.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BasicAclEntryAfterInvocationCollectionFilteringProvider
|
||||
implements AfterInvocationProvider, InitializingBean {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements AfterInvocationProvider,
|
||||
InitializingBean {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AclManager aclManager;
|
||||
private Class processDomainObjectClass = Object.class;
|
||||
private String processConfigAttribute = "AFTER_ACL_COLLECTION_READ";
|
||||
private int[] requirePermission = {SimpleAclEntry.READ};
|
||||
private Class processDomainObjectClass = Object.class;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setProcessDomainObjectClass(Class processDomainObjectClass) {
|
||||
Assert.notNull(processDomainObjectClass,
|
||||
"processDomainObjectClass cannot be set to null");
|
||||
this.processDomainObjectClass = processDomainObjectClass;
|
||||
}
|
||||
|
||||
public void setAclManager(AclManager aclManager) {
|
||||
this.aclManager = aclManager;
|
||||
}
|
||||
|
||||
public AclManager getAclManager() {
|
||||
return aclManager;
|
||||
}
|
||||
|
||||
public void setProcessConfigAttribute(String processConfigAttribute) {
|
||||
this.processConfigAttribute = processConfigAttribute;
|
||||
}
|
||||
|
||||
public String getProcessConfigAttribute() {
|
||||
return processConfigAttribute;
|
||||
}
|
||||
|
||||
public void setRequirePermission(int[] requirePermission) {
|
||||
this.requirePermission = requirePermission;
|
||||
}
|
||||
|
||||
public int[] getRequirePermission() {
|
||||
return requirePermission;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(processConfigAttribute,
|
||||
"A processConfigAttribute is mandatory");
|
||||
Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory");
|
||||
Assert.notNull(aclManager, "An aclManager is mandatory");
|
||||
|
||||
if ((requirePermission == null) || (requirePermission.length == 0)) {
|
||||
throw new IllegalArgumentException(
|
||||
"One or more requirePermission entries is mandatory");
|
||||
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
|
||||
}
|
||||
}
|
||||
|
||||
public Object decide(Authentication authentication, Object object,
|
||||
ConfigAttributeDefinition config, Object returnedObject)
|
||||
throws AccessDeniedException {
|
||||
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
|
||||
Object returnedObject) throws AccessDeniedException {
|
||||
Iterator iter = config.getConfigAttributes();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
@@ -203,7 +140,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider
|
||||
if (domainObject == null) {
|
||||
hasPermission = true;
|
||||
} else if (!processDomainObjectClass.isAssignableFrom(domainObject.getClass())) {
|
||||
hasPermission = true;
|
||||
hasPermission = true;
|
||||
} else {
|
||||
acls = aclManager.getAcls(domainObject, authentication);
|
||||
}
|
||||
@@ -212,21 +149,16 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider
|
||||
for (int i = 0; i < acls.length; i++) {
|
||||
// Locate processable AclEntrys
|
||||
if (acls[i] instanceof BasicAclEntry) {
|
||||
BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
|
||||
BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
|
||||
|
||||
// See if principal has any of the required permissions
|
||||
for (int y = 0; y < requirePermission.length;
|
||||
y++) {
|
||||
if (processableAcl.isPermitted(
|
||||
requirePermission[y])) {
|
||||
for (int y = 0; y < requirePermission.length; y++) {
|
||||
if (processableAcl.isPermitted(requirePermission[y])) {
|
||||
hasPermission = true;
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Principal is authorised for element: "
|
||||
+ domainObject
|
||||
+ " due to ACL: "
|
||||
+ processableAcl.toString());
|
||||
logger.debug("Principal is authorised for element: " + domainObject
|
||||
+ " due to ACL: " + processableAcl.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,9 +170,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider
|
||||
filterer.remove(domainObject);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Principal is NOT authorised for element: "
|
||||
+ domainObject);
|
||||
logger.debug("Principal is NOT authorised for element: " + domainObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,9 +182,37 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider
|
||||
return returnedObject;
|
||||
}
|
||||
|
||||
public AclManager getAclManager() {
|
||||
return aclManager;
|
||||
}
|
||||
|
||||
public String getProcessConfigAttribute() {
|
||||
return processConfigAttribute;
|
||||
}
|
||||
|
||||
public int[] getRequirePermission() {
|
||||
return requirePermission;
|
||||
}
|
||||
|
||||
public void setAclManager(AclManager aclManager) {
|
||||
this.aclManager = aclManager;
|
||||
}
|
||||
|
||||
public void setProcessConfigAttribute(String processConfigAttribute) {
|
||||
this.processConfigAttribute = processConfigAttribute;
|
||||
}
|
||||
|
||||
public void setProcessDomainObjectClass(Class processDomainObjectClass) {
|
||||
Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null");
|
||||
this.processDomainObjectClass = processDomainObjectClass;
|
||||
}
|
||||
|
||||
public void setRequirePermission(int[] requirePermission) {
|
||||
this.requirePermission = requirePermission;
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
if ((attribute.getAttribute() != null)
|
||||
&& attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
||||
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -262,8 +220,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation supports any type of class, because it does not
|
||||
* query the presented secure object.
|
||||
* This implementation supports any type of class, because it does not query the presented secure object.
|
||||
*
|
||||
* @param clazz the secure object
|
||||
*
|
||||
@@ -279,7 +236,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider
|
||||
* Filter strategy interface.
|
||||
*/
|
||||
interface Filterer {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Gets the filtered collection or array.
|
||||
@@ -308,11 +265,11 @@ interface Filterer {
|
||||
* A filter used to filter Collections.
|
||||
*/
|
||||
class CollectionFilterer implements Filterer {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Collection collection;
|
||||
|
||||
@@ -321,7 +278,7 @@ class CollectionFilterer implements Filterer {
|
||||
private Iterator collectionIter;
|
||||
private Set removeList;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
CollectionFilterer(Collection collection) {
|
||||
this.collection = collection;
|
||||
@@ -336,9 +293,10 @@ class CollectionFilterer implements Filterer {
|
||||
removeList = new HashSet();
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
*
|
||||
* @see org.acegisecurity.afterinvocation.Filterer#getFilteredObject()
|
||||
*/
|
||||
public Object getFilteredObject() {
|
||||
@@ -352,14 +310,15 @@ class CollectionFilterer implements Filterer {
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Original collection contained " + originalSize
|
||||
+ " elements; now contains " + collection.size() + " elements");
|
||||
logger.debug("Original collection contained " + originalSize + " elements; now contains "
|
||||
+ collection.size() + " elements");
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see org.acegisecurity.afterinvocation.Filterer#iterator()
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
@@ -369,6 +328,7 @@ class CollectionFilterer implements Filterer {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object)
|
||||
*/
|
||||
public void remove(Object object) {
|
||||
@@ -381,16 +341,16 @@ class CollectionFilterer implements Filterer {
|
||||
* A filter used to filter arrays.
|
||||
*/
|
||||
class ArrayFilterer implements Filterer {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Set removeList;
|
||||
private Object[] list;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
ArrayFilterer(Object[] list) {
|
||||
this.list = list;
|
||||
@@ -401,18 +361,17 @@ class ArrayFilterer implements Filterer {
|
||||
removeList = new HashSet();
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
*
|
||||
* @see org.acegisecurity.afterinvocation.Filterer#getFilteredObject()
|
||||
*/
|
||||
public Object getFilteredObject() {
|
||||
// Recreate an array of same type and filter the removed objects.
|
||||
int originalSize = list.length;
|
||||
int sizeOfResultingList = originalSize - removeList.size();
|
||||
Object[] filtered = (Object[]) Array.newInstance(list.getClass()
|
||||
.getComponentType(),
|
||||
sizeOfResultingList);
|
||||
Object[] filtered = (Object[]) Array.newInstance(list.getClass().getComponentType(), sizeOfResultingList);
|
||||
|
||||
for (int i = 0, j = 0; i < list.length; i++) {
|
||||
Object object = list[i];
|
||||
@@ -424,8 +383,7 @@ class ArrayFilterer implements Filterer {
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Original array contained " + originalSize
|
||||
+ " elements; now contains " + sizeOfResultingList
|
||||
logger.debug("Original array contained " + originalSize + " elements; now contains " + sizeOfResultingList
|
||||
+ " elements");
|
||||
}
|
||||
|
||||
@@ -433,6 +391,7 @@ class ArrayFilterer implements Filterer {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see org.acegisecurity.afterinvocation.Filterer#iterator()
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
@@ -440,6 +399,7 @@ class ArrayFilterer implements Filterer {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object)
|
||||
*/
|
||||
public void remove(Object object) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,116 +15,81 @@
|
||||
|
||||
package org.acegisecurity.afterinvocation;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.acegisecurity.AccessDeniedException;
|
||||
import org.acegisecurity.AcegiMessageSource;
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.ConfigAttribute;
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
|
||||
import org.acegisecurity.acl.AclEntry;
|
||||
import org.acegisecurity.acl.AclManager;
|
||||
import org.acegisecurity.acl.basic.BasicAclEntry;
|
||||
import org.acegisecurity.acl.basic.SimpleAclEntry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Given a domain object instance returned from a secure object invocation,
|
||||
* ensures the principal has appropriate permission as defined by the {@link
|
||||
* AclManager}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The <code>AclManager</code> is used to retrieve the access control list
|
||||
* (ACL) permissions associated with a domain object instance for the current
|
||||
* <code>Authentication</code> object. This class is designed to process
|
||||
* {@link AclEntry}s that are subclasses of {@link
|
||||
* org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are
|
||||
* obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This after invocation provider will fire if any {@link
|
||||
* ConfigAttribute#getAttribute()} matches the {@link
|
||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the
|
||||
* <code>AclManager</code> and ensure the principal is {@link
|
||||
* org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least
|
||||
* one of the {@link #requirePermission}s.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Often users will setup a <code>BasicAclEntryAfterInvocationProvider</code>
|
||||
* with a {@link #processConfigAttribute} of <code>AFTER_ACL_READ</code> and a
|
||||
* {@link #requirePermission} of <code>SimpleAclEntry.READ</code>. These are
|
||||
* also the defaults.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If the principal does not have sufficient permissions, an
|
||||
* <code>AccessDeniedException</code> will be thrown.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The <code>AclManager</code> is allowed to return any implementations of
|
||||
* <code>AclEntry</code> it wishes. However, this provider will only be able
|
||||
* to validate against <code>BasicAclEntry</code>s, and thus access will be
|
||||
* denied if no <code>AclEntry</code> is of type <code>BasicAclEntry</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If the provided <code>returnObject</code> is <code>null</code>, permission
|
||||
* will always be granted and <code>null</code> will be returned.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* All comparisons and prefixes are case sensitive.
|
||||
* </p>
|
||||
* <p>Given a domain object instance returned from a secure object invocation, ensures the principal has
|
||||
* appropriate permission as defined by the {@link AclManager}.</p>
|
||||
* <p>The <code>AclManager</code> is used to retrieve the access control list (ACL) permissions associated with a
|
||||
* domain object instance for the current <code>Authentication</code> object. This class is designed to process {@link
|
||||
* AclEntry}s that are subclasses of {@link org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are
|
||||
* obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.</p>
|
||||
* <p>This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
|
||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the <code>AclManager</code> and ensure the
|
||||
* principal is {@link org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link
|
||||
* #requirePermission}s.</p>
|
||||
* <p>Often users will setup a <code>BasicAclEntryAfterInvocationProvider</code> with a {@link
|
||||
* #processConfigAttribute} of <code>AFTER_ACL_READ</code> and a {@link #requirePermission} of
|
||||
* <code>SimpleAclEntry.READ</code>. These are also the defaults.</p>
|
||||
* <p>If the principal does not have sufficient permissions, an <code>AccessDeniedException</code> will be thrown.</p>
|
||||
* <p>The <code>AclManager</code> is allowed to return any implementations of <code>AclEntry</code> it wishes.
|
||||
* However, this provider will only be able to validate against <code>BasicAclEntry</code>s, and thus access will be
|
||||
* denied if no <code>AclEntry</code> is of type <code>BasicAclEntry</code>.</p>
|
||||
* <p>If the provided <code>returnObject</code> is <code>null</code>, permission will always be granted and
|
||||
* <code>null</code> will be returned.</p>
|
||||
* <p>All comparisons and prefixes are case sensitive.</p>
|
||||
*/
|
||||
public class BasicAclEntryAfterInvocationProvider
|
||||
implements AfterInvocationProvider, InitializingBean, MessageSourceAware {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class BasicAclEntryAfterInvocationProvider implements AfterInvocationProvider, InitializingBean,
|
||||
MessageSourceAware {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationProvider.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AclManager aclManager;
|
||||
private Class processDomainObjectClass = Object.class;
|
||||
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
|
||||
private String processConfigAttribute = "AFTER_ACL_READ";
|
||||
private int[] requirePermission = {SimpleAclEntry.READ};
|
||||
private Class processDomainObjectClass = Object.class;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void setProcessDomainObjectClass(Class processDomainObjectClass) {
|
||||
Assert.notNull(processDomainObjectClass,
|
||||
"processDomainObjectClass cannot be set to null");
|
||||
this.processDomainObjectClass = processDomainObjectClass;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(processConfigAttribute,
|
||||
"A processConfigAttribute is mandatory");
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory");
|
||||
Assert.notNull(aclManager, "An aclManager is mandatory");
|
||||
Assert.notNull(messages, "A message source must be set");
|
||||
|
||||
if ((requirePermission == null) || (requirePermission.length == 0)) {
|
||||
throw new IllegalArgumentException(
|
||||
"One or more requirePermission entries is mandatory");
|
||||
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
|
||||
}
|
||||
}
|
||||
|
||||
public Object decide(Authentication authentication, Object object,
|
||||
ConfigAttributeDefinition config, Object returnedObject)
|
||||
throws AccessDeniedException {
|
||||
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
|
||||
Object returnedObject) throws AccessDeniedException {
|
||||
Iterator iter = config.getConfigAttributes();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
@@ -141,7 +106,7 @@ public class BasicAclEntryAfterInvocationProvider
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (!processDomainObjectClass.isAssignableFrom(returnedObject.getClass())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Return object is not applicable for this provider, skipping");
|
||||
@@ -150,8 +115,7 @@ public class BasicAclEntryAfterInvocationProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
AclEntry[] acls = aclManager.getAcls(returnedObject,
|
||||
authentication);
|
||||
AclEntry[] acls = aclManager.getAcls(returnedObject, authentication);
|
||||
|
||||
if ((acls == null) || (acls.length == 0)) {
|
||||
throw new AccessDeniedException(messages.getMessage(
|
||||
@@ -169,10 +133,8 @@ public class BasicAclEntryAfterInvocationProvider
|
||||
for (int y = 0; y < requirePermission.length; y++) {
|
||||
if (processableAcl.isPermitted(requirePermission[y])) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Principal DOES have permission to return object: "
|
||||
+ returnedObject + " due to ACL: "
|
||||
+ processableAcl.toString());
|
||||
logger.debug("Principal DOES have permission to return object: " + returnedObject
|
||||
+ " due to ACL: " + processableAcl.toString());
|
||||
}
|
||||
|
||||
return returnedObject;
|
||||
@@ -216,13 +178,17 @@ public class BasicAclEntryAfterInvocationProvider
|
||||
this.processConfigAttribute = processConfigAttribute;
|
||||
}
|
||||
|
||||
public void setProcessDomainObjectClass(Class processDomainObjectClass) {
|
||||
Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null");
|
||||
this.processDomainObjectClass = processDomainObjectClass;
|
||||
}
|
||||
|
||||
public void setRequirePermission(int[] requirePermission) {
|
||||
this.requirePermission = requirePermission;
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
if ((attribute.getAttribute() != null)
|
||||
&& attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
||||
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -230,8 +196,7 @@ public class BasicAclEntryAfterInvocationProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation supports any type of class, because it does not
|
||||
* query the presented secure object.
|
||||
* This implementation supports any type of class, because it does not query the presented secure object.
|
||||
*
|
||||
* @param clazz the secure object
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,25 +19,21 @@
|
||||
package org.acegisecurity.captcha;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* return false if ny CaptchaChannelProcessorTemplate of mapped urls has been
|
||||
* requested more than thresold; <br>
|
||||
* Default keyword : REQUIRES_CAPTCHA_ABOVE_THRESOLD_REQUESTS
|
||||
* </p>
|
||||
* <p>return false if ny CaptchaChannelProcessorTemplate of mapped urls has been requested more than thresold; <br>
|
||||
* Default keyword : REQUIRES_CAPTCHA_ABOVE_THRESOLD_REQUESTS</p>
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessor
|
||||
extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
/** Keyword for this channelProcessor */
|
||||
public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_ABOVE_THRESOLD_REQUESTS";
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AlwaysTestAfterMaxRequestsCaptchaChannelProcessor() {
|
||||
@@ -45,7 +41,7 @@ public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessor
|
||||
this.setKeyword(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Verify wheter the context is valid concerning humanity
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,27 +12,25 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.acegisecurity.captcha;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* return false if thresold is greater than millis since last captcha test has occured;<br>
|
||||
* Default keyword : REQUIRES_CAPTCHA_AFTER_THRESOLD_IN_MILLIS
|
||||
* </p>
|
||||
* <p>return false if thresold is greater than millis since last captcha test has occured;<br>
|
||||
* Default keyword : REQUIRES_CAPTCHA_AFTER_THRESOLD_IN_MILLIS</p>
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor
|
||||
extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
/** Keyword for this channelProcessor */
|
||||
public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_AFTER_THRESOLD_IN_MILLIS";
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AlwaysTestAfterTimeInMillisCaptchaChannelProcessor() {
|
||||
@@ -40,7 +38,7 @@ public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor
|
||||
this.setKeyword(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Verify wheter the context is valid concerning humanity
|
||||
@@ -50,15 +48,12 @@ public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor
|
||||
* @return true if valid, false otherwise
|
||||
*/
|
||||
boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
|
||||
if ((System.currentTimeMillis()
|
||||
- context.getLastPassedCaptchaDateInMillis()) < getThresold()) {
|
||||
logger.debug(
|
||||
"context is valid : last passed captcha date - current time < thresold");
|
||||
if ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < getThresold()) {
|
||||
logger.debug("context is valid : last passed captcha date - current time < thresold");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
logger.debug(
|
||||
"context is not valid : last passed captcha date - current time > thresold");
|
||||
logger.debug("context is not valid : last passed captcha date - current time > thresold");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,26 +19,23 @@ import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* return false if thresold is lower than average time millis between any
|
||||
* CaptchaChannelProcessorTemplate mapped urls requests and is human;<br>
|
||||
* <p>return false if thresold is lower than average time millis between any CaptchaChannelProcessorTemplate mapped
|
||||
* urls requests and is human;<br>
|
||||
* Default keyword : REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS <br>
|
||||
* Note : before first humanity check
|
||||
* </p>
|
||||
* Note : before first humanity check</p>
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
/** Keyword for this channelProcessor */
|
||||
public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS";
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor() {
|
||||
@@ -46,7 +43,7 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
this.setKeyword(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Verify if thresold is > 0
|
||||
@@ -68,8 +65,7 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
|
||||
int req = context.getHumanRestrictedResourcesRequestsCount();
|
||||
float thresold = getThresold();
|
||||
float duration = System.currentTimeMillis()
|
||||
- context.getLastPassedCaptchaDateInMillis();
|
||||
float duration = System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis();
|
||||
float average;
|
||||
|
||||
if (req == 0) {
|
||||
@@ -79,13 +75,11 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
}
|
||||
|
||||
if (context.isHuman() && (average > thresold)) {
|
||||
logger.debug(
|
||||
"context is valid : average time between requests < thresold && is human");
|
||||
logger.debug("context is valid : average time between requests < thresold && is human");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
logger.debug(
|
||||
"context is not valid : request count > thresold or is not human");
|
||||
logger.debug("context is not valid : request count > thresold or is not human");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,8 +17,11 @@ package org.acegisecurity.captcha;
|
||||
|
||||
import org.acegisecurity.ConfigAttribute;
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
|
||||
import org.acegisecurity.intercept.web.FilterInvocation;
|
||||
|
||||
import org.acegisecurity.securechannel.ChannelEntryPoint;
|
||||
import org.acegisecurity.securechannel.ChannelProcessor;
|
||||
|
||||
@@ -37,67 +40,32 @@ import javax.servlet.ServletException;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* CaptchaChannel template : Ensures the user has enough human privileges by
|
||||
* review of the {@link CaptchaSecurityContext} and using an abstract routine
|
||||
* {@link #isContextValidConcerningHumanity(CaptchaSecurityContext)}
|
||||
* (implemented by sub classes)
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* The component uses 2 main parameters for its configuration :
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
* a keyword to be mapped to urls in the {@link
|
||||
* org.acegisecurity.securechannel.ChannelProcessingFilter} configuration<br>
|
||||
* default value provided by sub classes.
|
||||
* </li>
|
||||
* <li>
|
||||
* and a thresold : used by the routine {@link
|
||||
* #isContextValidConcerningHumanity(CaptchaSecurityContext)} to evaluate
|
||||
* whether the {@link CaptchaSecurityContext} is valid default value = 0
|
||||
* </li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>CaptchaChannel template : Ensures the user has enough human privileges by review of the {@link
|
||||
* CaptchaSecurityContext} and using an abstract routine {@link
|
||||
* #isContextValidConcerningHumanity(CaptchaSecurityContext)} (implemented by sub classes)</p>
|
||||
* <P>The component uses 2 main parameters for its configuration :
|
||||
* <ul>
|
||||
* <li>a keyword to be mapped to urls in the {@link
|
||||
* org.acegisecurity.securechannel.ChannelProcessingFilter} configuration<br>
|
||||
* default value provided by sub classes.</li>
|
||||
* <li>and a thresold : used by the routine {@link
|
||||
* #isContextValidConcerningHumanity(CaptchaSecurityContext)} to evaluate whether the {@link
|
||||
* CaptchaSecurityContext} is valid default value = 0</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @author marc antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class CaptchaChannelProcessorTemplate
|
||||
implements ChannelProcessor, InitializingBean {
|
||||
//~ Instance fields ========================================================
|
||||
public abstract class CaptchaChannelProcessorTemplate implements ChannelProcessor, InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected Log logger = LogFactory.getLog(this.getClass());
|
||||
private ChannelEntryPoint entryPoint;
|
||||
protected Log logger = LogFactory.getLog(this.getClass());
|
||||
private String keyword = null;
|
||||
private int thresold = 0;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setEntryPoint(ChannelEntryPoint entryPoint) {
|
||||
this.entryPoint = entryPoint;
|
||||
}
|
||||
|
||||
public ChannelEntryPoint getEntryPoint() {
|
||||
return entryPoint;
|
||||
}
|
||||
|
||||
public void setKeyword(String keyword) {
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public void setThresold(int thresold) {
|
||||
this.thresold = thresold;
|
||||
}
|
||||
|
||||
public int getThresold() {
|
||||
return thresold;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Verify if entryPoint and keyword are ok
|
||||
@@ -109,8 +77,8 @@ public abstract class CaptchaChannelProcessorTemplate
|
||||
Assert.hasLength(keyword, "keyword required");
|
||||
}
|
||||
|
||||
public void decide(FilterInvocation invocation,
|
||||
ConfigAttributeDefinition config) throws IOException, ServletException {
|
||||
public void decide(FilterInvocation invocation, ConfigAttributeDefinition config)
|
||||
throws IOException, ServletException {
|
||||
if ((invocation == null) || (config == null)) {
|
||||
throw new IllegalArgumentException("Nulls cannot be provided");
|
||||
}
|
||||
@@ -127,12 +95,10 @@ public abstract class CaptchaChannelProcessorTemplate
|
||||
logger.debug("supports this attribute : " + attribute);
|
||||
|
||||
if (!isContextValidConcerningHumanity(context)) {
|
||||
logger.debug(
|
||||
"context is not allowed to access ressource, redirect to captcha entry point");
|
||||
logger.debug("context is not allowed to access ressource, redirect to captcha entry point");
|
||||
redirectToEntryPoint(invocation);
|
||||
} else {
|
||||
logger.debug(
|
||||
"has been successfully checked this keyword, increment request count");
|
||||
logger.debug("has been successfully checked this keyword, increment request count");
|
||||
context.incrementHumanRestrictedRessoucesRequestsCount();
|
||||
}
|
||||
} else {
|
||||
@@ -141,16 +107,19 @@ public abstract class CaptchaChannelProcessorTemplate
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
if ((attribute != null) && (keyword.equals(attribute.getAttribute()))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
public ChannelEntryPoint getEntryPoint() {
|
||||
return entryPoint;
|
||||
}
|
||||
|
||||
abstract boolean isContextValidConcerningHumanity(
|
||||
CaptchaSecurityContext context);
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public int getThresold() {
|
||||
return thresold;
|
||||
}
|
||||
|
||||
abstract boolean isContextValidConcerningHumanity(CaptchaSecurityContext context);
|
||||
|
||||
private void redirectToEntryPoint(FilterInvocation invocation)
|
||||
throws IOException, ServletException {
|
||||
@@ -160,4 +129,24 @@ public abstract class CaptchaChannelProcessorTemplate
|
||||
|
||||
entryPoint.commence(invocation.getRequest(), invocation.getResponse());
|
||||
}
|
||||
|
||||
public void setEntryPoint(ChannelEntryPoint entryPoint) {
|
||||
this.entryPoint = entryPoint;
|
||||
}
|
||||
|
||||
public void setKeyword(String keyword) {
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
public void setThresold(int thresold) {
|
||||
this.thresold = thresold;
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
if ((attribute != null) && (keyword.equals(attribute.getAttribute()))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.acegisecurity.captcha;
|
||||
|
||||
import org.acegisecurity.securechannel.ChannelEntryPoint;
|
||||
|
||||
import org.acegisecurity.util.PortMapper;
|
||||
import org.acegisecurity.util.PortMapperImpl;
|
||||
import org.acegisecurity.util.PortResolver;
|
||||
@@ -43,47 +44,25 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* The captcha entry point : redirect to the captcha test page. <br>
|
||||
*
|
||||
* <p>
|
||||
* This entry point can force the use of SSL : see {@link #getForceHttps()}<br>
|
||||
* </p>
|
||||
* This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}<br>
|
||||
* / Original request can be added to the redirect path using a custom
|
||||
* translation : see {@link #setIncludeOriginalRequest(boolean)}<br>
|
||||
* Original request is translated using URLEncoding and the following
|
||||
* translation mapping in the redirect url :
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
* original url => {@link #getOriginalRequestUrlParameterName()}
|
||||
* </li>
|
||||
* <li>
|
||||
* If {@link #isIncludeOriginalParameters()}
|
||||
* </li>
|
||||
* <li>
|
||||
* original method => {@link #getOriginalRequestMethodParameterName()}
|
||||
* </li>
|
||||
* <li>
|
||||
* original parameters => {@link #getOriginalRequestParametersParameterName()}
|
||||
* </li>
|
||||
* <li>
|
||||
* The original parameters string is contructed using :
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
* a parameter separator {@link #getOriginalRequestParametersSeparator()}
|
||||
* </li>
|
||||
* <li>
|
||||
* a parameter name value pair separator for each parameter {@link
|
||||
* #getOriginalRequestParametersNameValueSeparator()}
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <br><br>
|
||||
* The captcha entry point : redirect to the captcha test page. <br><p>This entry point can force the use of SSL :
|
||||
* see {@link #getForceHttps()}<br></p>
|
||||
* This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}<br>
|
||||
* / Original request can be added to the redirect path using a custom translation : see {@link #setIncludeOriginalRequest(boolean)}<br>
|
||||
* Original request is translated using URLEncoding and the following translation mapping in the redirect url :
|
||||
* <ul>
|
||||
* <li>original url => {@link #getOriginalRequestUrlParameterName()}</li>
|
||||
* <li>If {@link #isIncludeOriginalParameters()}</li>
|
||||
* <li>original method => {@link #getOriginalRequestMethodParameterName()}</li>
|
||||
* <li>original parameters => {@link #getOriginalRequestParametersParameterName()}</li>
|
||||
* <li>The original parameters string is contructed using :
|
||||
* <ul>
|
||||
* <li>a parameter separator {@link #getOriginalRequestParametersSeparator()}</li>
|
||||
* <li>a parameter name value pair separator for each parameter {@link
|
||||
* #getOriginalRequestParametersNameValueSeparator()}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* <br><br>
|
||||
* Default values :<br>
|
||||
* forceHttps = false<br>
|
||||
* includesOriginalRequest = true<br>
|
||||
@@ -100,13 +79,13 @@ import javax.servlet.http.HttpServletResponse;
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =============================================
|
||||
private static final Log logger = LogFactory.getLog(CaptchaEntryPoint.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
// ~ Instance fields
|
||||
// ========================================================
|
||||
@@ -124,197 +103,24 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
|
||||
private boolean includeOriginalRequest = true;
|
||||
private boolean isOutsideWebApp = false;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
/**
|
||||
* The URL where the <code>CaptchaProcessingFilter</code> login page can be
|
||||
* found. Should be relative to the web-app context path, and include a
|
||||
* leading <code>/</code>
|
||||
*
|
||||
* @param captchaFormUrl
|
||||
*/
|
||||
public void setCaptchaFormUrl(String captchaFormUrl) {
|
||||
this.captchaFormUrl = captchaFormUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return the captcha test page to redirect to.
|
||||
*/
|
||||
public String getCaptchaFormUrl() {
|
||||
return captchaFormUrl;
|
||||
}
|
||||
|
||||
// ~ Methods
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Set to true to force captcha form access to be via https. If this value
|
||||
* is ture (the default is false), and the incoming request for the
|
||||
* protected resource which triggered the interceptor was not already
|
||||
* <code>https</code>, then
|
||||
*
|
||||
* @param forceHttps
|
||||
*/
|
||||
public void setForceHttps(boolean forceHttps) {
|
||||
this.forceHttps = forceHttps;
|
||||
}
|
||||
|
||||
public boolean getForceHttps() {
|
||||
return forceHttps;
|
||||
}
|
||||
|
||||
public void setIncludeOriginalParameters(boolean includeOriginalParameters) {
|
||||
this.includeOriginalParameters = includeOriginalParameters;
|
||||
}
|
||||
|
||||
public boolean isIncludeOriginalParameters() {
|
||||
return includeOriginalParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to true, the original request url will be appended to the
|
||||
* redirect url using the {@link #getOriginalRequestUrlParameterName()}.
|
||||
*
|
||||
* @param includeOriginalRequest
|
||||
*/
|
||||
public void setIncludeOriginalRequest(boolean includeOriginalRequest) {
|
||||
this.includeOriginalRequest = includeOriginalRequest;
|
||||
}
|
||||
|
||||
public boolean isIncludeOriginalRequest() {
|
||||
return includeOriginalRequest;
|
||||
}
|
||||
|
||||
public void setOriginalRequestMethodParameterName(
|
||||
String originalRequestMethodParameterName) {
|
||||
this.originalRequestMethodParameterName = originalRequestMethodParameterName;
|
||||
}
|
||||
|
||||
public String getOriginalRequestMethodParameterName() {
|
||||
return originalRequestMethodParameterName;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersNameValueSeparator(
|
||||
String originalRequestParametersNameValueSeparator) {
|
||||
this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersNameValueSeparator() {
|
||||
return originalRequestParametersNameValueSeparator;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersParameterName(
|
||||
String originalRequestParametersParameterName) {
|
||||
this.originalRequestParametersParameterName = originalRequestParametersParameterName;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersParameterName() {
|
||||
return originalRequestParametersParameterName;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersSeparator(
|
||||
String originalRequestParametersSeparator) {
|
||||
this.originalRequestParametersSeparator = originalRequestParametersSeparator;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersSeparator() {
|
||||
return originalRequestParametersSeparator;
|
||||
}
|
||||
|
||||
public void setOriginalRequestUrlParameterName(
|
||||
String originalRequestUrlParameterName) {
|
||||
this.originalRequestUrlParameterName = originalRequestUrlParameterName;
|
||||
}
|
||||
|
||||
public String getOriginalRequestUrlParameterName() {
|
||||
return originalRequestUrlParameterName;
|
||||
}
|
||||
|
||||
/**
|
||||
* if set to true, the {@link #commence(ServletRequest, ServletResponse)}
|
||||
* method uses the {@link #getCaptchaFormUrl()} as a complete URL, else it
|
||||
* as a 'inside WebApp' path.
|
||||
*
|
||||
* @param isOutsideWebApp
|
||||
*/
|
||||
public void setOutsideWebApp(boolean isOutsideWebApp) {
|
||||
this.isOutsideWebApp = isOutsideWebApp;
|
||||
}
|
||||
|
||||
public boolean isOutsideWebApp() {
|
||||
return isOutsideWebApp;
|
||||
}
|
||||
|
||||
public void setPortMapper(PortMapper portMapper) {
|
||||
this.portMapper = portMapper;
|
||||
}
|
||||
|
||||
public PortMapper getPortMapper() {
|
||||
return portMapper;
|
||||
}
|
||||
|
||||
public void setPortResolver(PortResolver portResolver) {
|
||||
this.portResolver = portResolver;
|
||||
}
|
||||
|
||||
public PortResolver getPortResolver() {
|
||||
return portResolver;
|
||||
}
|
||||
|
||||
public void setUrlEncodingCharset(String urlEncodingCharset) {
|
||||
this.urlEncodingCharset = urlEncodingCharset;
|
||||
}
|
||||
|
||||
public String getUrlEncodingCharset() {
|
||||
return urlEncodingCharset;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.hasLength(captchaFormUrl, "captchaFormUrl must be specified");
|
||||
Assert.hasLength(originalRequestMethodParameterName,
|
||||
"originalRequestMethodParameterName must be specified");
|
||||
Assert.hasLength(originalRequestMethodParameterName, "originalRequestMethodParameterName must be specified");
|
||||
Assert.hasLength(originalRequestParametersNameValueSeparator,
|
||||
"originalRequestParametersNameValueSeparator must be specified");
|
||||
Assert.hasLength(originalRequestParametersParameterName,
|
||||
"originalRequestParametersParameterName must be specified");
|
||||
Assert.hasLength(originalRequestParametersSeparator,
|
||||
"originalRequestParametersSeparator must be specified");
|
||||
Assert.hasLength(originalRequestUrlParameterName,
|
||||
"originalRequestUrlParameterName must be specified");
|
||||
Assert.hasLength(urlEncodingCharset,
|
||||
"urlEncodingCharset must be specified");
|
||||
Assert.hasLength(originalRequestParametersSeparator, "originalRequestParametersSeparator must be specified");
|
||||
Assert.hasLength(originalRequestUrlParameterName, "originalRequestUrlParameterName must be specified");
|
||||
Assert.hasLength(urlEncodingCharset, "urlEncodingCharset must be specified");
|
||||
Assert.notNull(portMapper, "portMapper must be specified");
|
||||
Assert.notNull(portResolver, "portResolver must be specified");
|
||||
URLEncoder.encode(" fzaef <20>& <20> ", urlEncodingCharset);
|
||||
}
|
||||
|
||||
public void commence(ServletRequest request, ServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
StringBuffer redirectUrl = new StringBuffer();
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
|
||||
if (isOutsideWebApp) {
|
||||
redirectUrl = redirectUrl.append(captchaFormUrl);
|
||||
} else {
|
||||
buildInternalRedirect(redirectUrl, req);
|
||||
}
|
||||
|
||||
if (includeOriginalRequest) {
|
||||
includeOriginalRequest(redirectUrl, req);
|
||||
}
|
||||
|
||||
// add post parameter? DONE!
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Redirecting to: " + redirectUrl);
|
||||
}
|
||||
|
||||
((HttpServletResponse) response).sendRedirect(redirectUrl.toString());
|
||||
}
|
||||
|
||||
private void buildInternalRedirect(StringBuffer redirectUrl,
|
||||
HttpServletRequest req) {
|
||||
private void buildInternalRedirect(StringBuffer redirectUrl, HttpServletRequest req) {
|
||||
// construct it
|
||||
StringBuffer simpleRedirect = new StringBuffer();
|
||||
|
||||
@@ -373,8 +179,75 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
|
||||
}
|
||||
}
|
||||
|
||||
private void includeOriginalRequest(StringBuffer redirectUrl,
|
||||
HttpServletRequest req) {
|
||||
public void commence(ServletRequest request, ServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
StringBuffer redirectUrl = new StringBuffer();
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
|
||||
if (isOutsideWebApp) {
|
||||
redirectUrl = redirectUrl.append(captchaFormUrl);
|
||||
} else {
|
||||
buildInternalRedirect(redirectUrl, req);
|
||||
}
|
||||
|
||||
if (includeOriginalRequest) {
|
||||
includeOriginalRequest(redirectUrl, req);
|
||||
}
|
||||
|
||||
// add post parameter? DONE!
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Redirecting to: " + redirectUrl);
|
||||
}
|
||||
|
||||
((HttpServletResponse) response).sendRedirect(redirectUrl.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return the captcha test page to redirect to.
|
||||
*/
|
||||
public String getCaptchaFormUrl() {
|
||||
return captchaFormUrl;
|
||||
}
|
||||
|
||||
public boolean getForceHttps() {
|
||||
return forceHttps;
|
||||
}
|
||||
|
||||
public String getOriginalRequestMethodParameterName() {
|
||||
return originalRequestMethodParameterName;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersNameValueSeparator() {
|
||||
return originalRequestParametersNameValueSeparator;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersParameterName() {
|
||||
return originalRequestParametersParameterName;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersSeparator() {
|
||||
return originalRequestParametersSeparator;
|
||||
}
|
||||
|
||||
public String getOriginalRequestUrlParameterName() {
|
||||
return originalRequestUrlParameterName;
|
||||
}
|
||||
|
||||
public PortMapper getPortMapper() {
|
||||
return portMapper;
|
||||
}
|
||||
|
||||
public PortResolver getPortResolver() {
|
||||
return portResolver;
|
||||
}
|
||||
|
||||
public String getUrlEncodingCharset() {
|
||||
return urlEncodingCharset;
|
||||
}
|
||||
|
||||
private void includeOriginalRequest(StringBuffer redirectUrl, HttpServletRequest req) {
|
||||
// add original request to the url
|
||||
if (redirectUrl.indexOf("?") >= 0) {
|
||||
redirectUrl.append("&");
|
||||
@@ -386,8 +259,7 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
|
||||
redirectUrl.append("=");
|
||||
|
||||
try {
|
||||
redirectUrl.append(URLEncoder.encode(req.getRequestURL().toString(),
|
||||
urlEncodingCharset));
|
||||
redirectUrl.append(URLEncoder.encode(req.getRequestURL().toString(), urlEncodingCharset));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.warn(e);
|
||||
}
|
||||
@@ -423,11 +295,101 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
|
||||
}
|
||||
|
||||
try {
|
||||
redirectUrl.append(URLEncoder.encode(qp.toString(),
|
||||
urlEncodingCharset));
|
||||
redirectUrl.append(URLEncoder.encode(qp.toString(), urlEncodingCharset));
|
||||
} catch (Exception e) {
|
||||
logger.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIncludeOriginalParameters() {
|
||||
return includeOriginalParameters;
|
||||
}
|
||||
|
||||
public boolean isIncludeOriginalRequest() {
|
||||
return includeOriginalRequest;
|
||||
}
|
||||
|
||||
public boolean isOutsideWebApp() {
|
||||
return isOutsideWebApp;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL where the <code>CaptchaProcessingFilter</code> login page can be found. Should be relative to
|
||||
* the web-app context path, and include a leading <code>/</code>
|
||||
*
|
||||
* @param captchaFormUrl
|
||||
*/
|
||||
public void setCaptchaFormUrl(String captchaFormUrl) {
|
||||
this.captchaFormUrl = captchaFormUrl;
|
||||
}
|
||||
|
||||
// ~ Methods
|
||||
// ================================================================
|
||||
/**
|
||||
* Set to true to force captcha form access to be via https. If this value is ture (the default is false),
|
||||
* and the incoming request for the protected resource which triggered the interceptor was not already
|
||||
* <code>https</code>, then
|
||||
*
|
||||
* @param forceHttps
|
||||
*/
|
||||
public void setForceHttps(boolean forceHttps) {
|
||||
this.forceHttps = forceHttps;
|
||||
}
|
||||
|
||||
public void setIncludeOriginalParameters(boolean includeOriginalParameters) {
|
||||
this.includeOriginalParameters = includeOriginalParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to true, the original request url will be appended to the redirect url using the {@link
|
||||
* #getOriginalRequestUrlParameterName()}.
|
||||
*
|
||||
* @param includeOriginalRequest
|
||||
*/
|
||||
public void setIncludeOriginalRequest(boolean includeOriginalRequest) {
|
||||
this.includeOriginalRequest = includeOriginalRequest;
|
||||
}
|
||||
|
||||
public void setOriginalRequestMethodParameterName(String originalRequestMethodParameterName) {
|
||||
this.originalRequestMethodParameterName = originalRequestMethodParameterName;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersNameValueSeparator(String originalRequestParametersNameValueSeparator) {
|
||||
this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersParameterName(String originalRequestParametersParameterName) {
|
||||
this.originalRequestParametersParameterName = originalRequestParametersParameterName;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersSeparator(String originalRequestParametersSeparator) {
|
||||
this.originalRequestParametersSeparator = originalRequestParametersSeparator;
|
||||
}
|
||||
|
||||
public void setOriginalRequestUrlParameterName(String originalRequestUrlParameterName) {
|
||||
this.originalRequestUrlParameterName = originalRequestUrlParameterName;
|
||||
}
|
||||
|
||||
/**
|
||||
* if set to true, the {@link #commence(ServletRequest, ServletResponse)} method uses the {@link
|
||||
* #getCaptchaFormUrl()} as a complete URL, else it as a 'inside WebApp' path.
|
||||
*
|
||||
* @param isOutsideWebApp
|
||||
*/
|
||||
public void setOutsideWebApp(boolean isOutsideWebApp) {
|
||||
this.isOutsideWebApp = isOutsideWebApp;
|
||||
}
|
||||
|
||||
public void setPortMapper(PortMapper portMapper) {
|
||||
this.portMapper = portMapper;
|
||||
}
|
||||
|
||||
public void setPortResolver(PortResolver portResolver) {
|
||||
this.portResolver = portResolver;
|
||||
}
|
||||
|
||||
public void setUrlEncodingCharset(String urlEncodingCharset) {
|
||||
this.urlEncodingCharset = urlEncodingCharset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,12 +24,26 @@ import org.acegisecurity.context.SecurityContext;
|
||||
* @author marc antoine garrigue
|
||||
*/
|
||||
public interface CaptchaSecurityContext extends SecurityContext {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* set human attribute, should called after captcha validation.
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return number of human restricted resources requests since the last passed captcha.
|
||||
*/
|
||||
void setHuman();
|
||||
int getHumanRestrictedResourcesRequestsCount();
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return the date of the last passed Captcha in millis, 0 if the user never passed captcha.
|
||||
*/
|
||||
long getLastPassedCaptchaDateInMillis();
|
||||
|
||||
/**
|
||||
* Method to increment the human Restricted Resrouces Requests Count;
|
||||
*/
|
||||
void incrementHumanRestrictedRessoucesRequestsCount();
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
@@ -39,23 +53,7 @@ public interface CaptchaSecurityContext extends SecurityContext {
|
||||
boolean isHuman();
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return number of human restricted resources requests since the last
|
||||
* passed captcha.
|
||||
* set human attribute, should called after captcha validation.
|
||||
*/
|
||||
int getHumanRestrictedResourcesRequestsCount();
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return the date of the last passed Captcha in millis, 0 if the user
|
||||
* never passed captcha.
|
||||
*/
|
||||
long getLastPassedCaptchaDateInMillis();
|
||||
|
||||
/**
|
||||
* Method to increment the human Restricted Resrouces Requests Count;
|
||||
*/
|
||||
void incrementHumanRestrictedRessoucesRequestsCount();
|
||||
void setHuman();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,15 +23,14 @@ import org.acegisecurity.context.SecurityContextImpl;
|
||||
*
|
||||
* @author mag
|
||||
*/
|
||||
public class CaptchaSecurityContextImpl extends SecurityContextImpl
|
||||
implements CaptchaSecurityContext {
|
||||
//~ Instance fields ========================================================
|
||||
public class CaptchaSecurityContextImpl extends SecurityContextImpl implements CaptchaSecurityContext {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private boolean human;
|
||||
private int humanRestrictedResourcesRequestsCount;
|
||||
private long lastPassedCaptchaDate;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public CaptchaSecurityContextImpl() {
|
||||
super();
|
||||
@@ -40,19 +39,28 @@ public class CaptchaSecurityContextImpl extends SecurityContextImpl
|
||||
humanRestrictedResourcesRequestsCount = 0;
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Reset the lastPassedCaptchaDate and count.
|
||||
*/
|
||||
public void setHuman() {
|
||||
this.human = true;
|
||||
this.lastPassedCaptchaDate = System.currentTimeMillis();
|
||||
this.humanRestrictedResourcesRequestsCount = 0;
|
||||
}
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof CaptchaSecurityContextImpl) {
|
||||
CaptchaSecurityContextImpl rhs = (CaptchaSecurityContextImpl) obj;
|
||||
|
||||
public boolean isHuman() {
|
||||
return human;
|
||||
if (this.isHuman() != rhs.isHuman()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.getHumanRestrictedResourcesRequestsCount() != rhs.getHumanRestrictedResourcesRequestsCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.getLastPassedCaptchaDateInMillis() != rhs.getLastPassedCaptchaDateInMillis()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getHumanRestrictedResourcesRequestsCount() {
|
||||
@@ -63,6 +71,18 @@ public class CaptchaSecurityContextImpl extends SecurityContextImpl
|
||||
return lastPassedCaptchaDate;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int code = super.hashCode();
|
||||
code ^= this.humanRestrictedResourcesRequestsCount;
|
||||
code ^= this.lastPassedCaptchaDate;
|
||||
|
||||
if (this.isHuman()) {
|
||||
code ^= -37;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to increment the human Restricted Resrouces Requests Count;
|
||||
*/
|
||||
@@ -70,30 +90,16 @@ public class CaptchaSecurityContextImpl extends SecurityContextImpl
|
||||
humanRestrictedResourcesRequestsCount++;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof CaptchaSecurityContextImpl) {
|
||||
CaptchaSecurityContextImpl rhs = (CaptchaSecurityContextImpl) obj;
|
||||
if (this.isHuman() != rhs.isHuman()) {
|
||||
return false;
|
||||
}
|
||||
if (this.getHumanRestrictedResourcesRequestsCount() != rhs.getHumanRestrictedResourcesRequestsCount()) {
|
||||
return false;
|
||||
}
|
||||
if (this.getLastPassedCaptchaDateInMillis() != rhs.getLastPassedCaptchaDateInMillis()) {
|
||||
return false;
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean isHuman() {
|
||||
return human;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int code = super.hashCode();
|
||||
code ^= this.humanRestrictedResourcesRequestsCount;
|
||||
code ^= this.lastPassedCaptchaDate;
|
||||
if (this.isHuman()) {
|
||||
code ^= -37;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
/**
|
||||
* Reset the lastPassedCaptchaDate and count.
|
||||
*/
|
||||
public void setHuman() {
|
||||
this.human = true;
|
||||
this.lastPassedCaptchaDate = System.currentTimeMillis();
|
||||
this.humanRestrictedResourcesRequestsCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
package org.acegisecurity.captcha;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provide a common interface for captcha validation.
|
||||
*
|
||||
@@ -24,7 +22,7 @@ package org.acegisecurity.captcha;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface CaptchaServiceProxy {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
@@ -32,8 +30,7 @@ public interface CaptchaServiceProxy {
|
||||
* @param id the id token
|
||||
* @param captchaResponse the user response
|
||||
*
|
||||
* @return true if the response is validated by the back end captcha
|
||||
* service.
|
||||
* @return true if the response is validated by the back end captcha service.
|
||||
*/
|
||||
boolean validateReponseForId(String id, Object captchaResponse);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,64 +31,39 @@ import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* Filter for web integration of the {@link CaptchaServiceProxy}. <br>
|
||||
* It basically intercept calls containing the specific validation parameter,
|
||||
* use the {@link CaptchaServiceProxy} to validate the request, and update the
|
||||
* {@link CaptchaSecurityContext} if the request passed the validation. <br>
|
||||
* This Filter should be placed after the ContextIntegration filter and before
|
||||
* the {@link CaptchaChannelProcessorTemplate} filter in the filter stack in
|
||||
* order to update the {@link CaptchaSecurityContext} before the humanity
|
||||
* verification routine occurs. <br>
|
||||
* This filter should only be used in conjunction with the {@link
|
||||
* CaptchaSecurityContext}<br>
|
||||
* It basically intercept calls containing the specific validation parameter, use the {@link CaptchaServiceProxy} to
|
||||
* validate the request, and update the {@link CaptchaSecurityContext} if the request passed the validation. <br>
|
||||
* This Filter should be placed after the ContextIntegration filter and before the {@link
|
||||
* CaptchaChannelProcessorTemplate} filter in the filter stack in order to update the {@link CaptchaSecurityContext}
|
||||
* before the humanity verification routine occurs. <br>
|
||||
* This filter should only be used in conjunction with the {@link CaptchaSecurityContext}<br>
|
||||
*
|
||||
* @author marc antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaValidationProcessingFilter implements InitializingBean,
|
||||
Filter {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class CaptchaValidationProcessingFilter implements InitializingBean, Filter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =============================================
|
||||
protected static final Log logger = LogFactory.getLog(CaptchaValidationProcessingFilter.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
// ~ Instance fields
|
||||
// ========================================================
|
||||
private CaptchaServiceProxy captchaService;
|
||||
private String captchaValidationParameter = "_captcha_parameter";
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setCaptchaService(CaptchaServiceProxy captchaService) {
|
||||
this.captchaService = captchaService;
|
||||
}
|
||||
|
||||
// ~ Methods
|
||||
// ================================================================
|
||||
public CaptchaServiceProxy getCaptchaService() {
|
||||
return captchaService;
|
||||
}
|
||||
|
||||
public void setCaptchaValidationParameter(String captchaValidationParameter) {
|
||||
this.captchaValidationParameter = captchaValidationParameter;
|
||||
}
|
||||
|
||||
public String getCaptchaValidationParameter() {
|
||||
return captchaValidationParameter;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.captchaService == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"CaptchaServiceProxy must be defined ");
|
||||
throw new IllegalArgumentException("CaptchaServiceProxy must be defined ");
|
||||
}
|
||||
|
||||
if ((this.captchaValidationParameter == null)
|
||||
|| "".equals(captchaValidationParameter)) {
|
||||
throw new IllegalArgumentException(
|
||||
"captchaValidationParameter must not be empty or null");
|
||||
if ((this.captchaValidationParameter == null) || "".equals(captchaValidationParameter)) {
|
||||
throw new IllegalArgumentException("captchaValidationParameter must not be empty or null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,12 +72,11 @@ public class CaptchaValidationProcessingFilter implements InitializingBean,
|
||||
*/
|
||||
public void destroy() {}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
String captcha_reponse = request.getParameter(captchaValidationParameter);
|
||||
|
||||
if ((request != null) && request instanceof HttpServletRequest
|
||||
&& (captcha_reponse != null)) {
|
||||
if ((request != null) && request instanceof HttpServletRequest && (captcha_reponse != null)) {
|
||||
logger.debug("captcha validation parameter found");
|
||||
|
||||
// validate the request against CaptchaServiceProxy
|
||||
@@ -115,23 +89,19 @@ public class CaptchaValidationProcessingFilter implements InitializingBean,
|
||||
|
||||
if (session != null) {
|
||||
String id = session.getId();
|
||||
valid = this.captchaService.validateReponseForId(id,
|
||||
captcha_reponse);
|
||||
logger.debug("captchaServiceProxy says : request is valid = "
|
||||
+ valid);
|
||||
valid = this.captchaService.validateReponseForId(id, captcha_reponse);
|
||||
logger.debug("captchaServiceProxy says : request is valid = " + valid);
|
||||
|
||||
if (valid) {
|
||||
logger.debug("update the context");
|
||||
((CaptchaSecurityContext) SecurityContextHolder.getContext())
|
||||
.setHuman();
|
||||
((CaptchaSecurityContext) SecurityContextHolder.getContext()).setHuman();
|
||||
|
||||
//logger.debug("retrieve original request from ")
|
||||
} else {
|
||||
logger.debug("captcha test failed");
|
||||
}
|
||||
} else {
|
||||
logger.debug(
|
||||
"no session found, user don't even ask a captcha challenge");
|
||||
logger.debug("no session found, user don't even ask a captcha challenge");
|
||||
}
|
||||
} else {
|
||||
logger.debug("captcha validation parameter not found, do nothing");
|
||||
@@ -144,6 +114,16 @@ public class CaptchaValidationProcessingFilter implements InitializingBean,
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
// ~ Methods
|
||||
// ================================================================
|
||||
public CaptchaServiceProxy getCaptchaService() {
|
||||
return captchaService;
|
||||
}
|
||||
|
||||
public String getCaptchaValidationParameter() {
|
||||
return captchaValidationParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing. We use IoC container lifecycle services instead.
|
||||
*
|
||||
@@ -152,4 +132,12 @@ public class CaptchaValidationProcessingFilter implements InitializingBean,
|
||||
* @throws ServletException ignored
|
||||
*/
|
||||
public void init(FilterConfig filterConfig) throws ServletException {}
|
||||
|
||||
public void setCaptchaService(CaptchaServiceProxy captchaService) {
|
||||
this.captchaService = captchaService;
|
||||
}
|
||||
|
||||
public void setCaptchaValidationParameter(String captchaValidationParameter) {
|
||||
this.captchaValidationParameter = captchaValidationParameter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,43 +12,38 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.acegisecurity.captcha;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* return false if ny CaptchaChannelProcessorTemplate mapped urls has been
|
||||
* requested more than thresold and humanity is false; <br>
|
||||
* Default keyword : REQUIRES_CAPTCHA_ONCE_ABOVE_THRESOLD_REQUESTS
|
||||
* </p>
|
||||
* <p>return false if ny CaptchaChannelProcessorTemplate mapped urls has been requested more than thresold and
|
||||
* humanity is false; <br>
|
||||
* Default keyword : REQUIRES_CAPTCHA_ONCE_ABOVE_THRESOLD_REQUESTS</p>
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class TestOnceAfterMaxRequestsCaptchaChannelProcessor
|
||||
extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class TestOnceAfterMaxRequestsCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_ONCE_ABOVE_THRESOLD_REQUESTS";
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public TestOnceAfterMaxRequestsCaptchaChannelProcessor() {
|
||||
super();
|
||||
this.setKeyword(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
|
||||
if (context.isHuman()
|
||||
|| (context.getHumanRestrictedResourcesRequestsCount() < getThresold())) {
|
||||
logger.debug(
|
||||
"context is valid concerning humanity or request count < thresold");
|
||||
if (context.isHuman() || (context.getHumanRestrictedResourcesRequestsCount() < getThresold())) {
|
||||
logger.debug("context is valid concerning humanity or request count < thresold");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
logger.debug(
|
||||
"context is not valid concerning humanity and request count > thresold");
|
||||
logger.debug("context is not valid concerning humanity and request count > thresold");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,20 +12,22 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.acegisecurity.concurrent;
|
||||
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Thrown by <code>ConcurrentSessionControllerImpl</code> if
|
||||
* an attempt is made to login and the user has already exceeded
|
||||
* their maxmimum allowed sessions.
|
||||
* Thrown by <code>ConcurrentSessionControllerImpl</code> if an attempt is made to login and the user has already
|
||||
* exceeded their maxmimum allowed sessions.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ConcurrentLoginException extends AuthenticationException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public ConcurrentLoginException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,38 +28,28 @@ import org.acegisecurity.AuthenticationException;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface ConcurrentSessionController {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Called by any class that wishes to know whether the current
|
||||
* authentication request should be permitted. Generally callers will be
|
||||
* <code>AuthenticationManager</code>s before they authenticate, but could
|
||||
* equally include <code>Filter</code>s or other interceptors that wish to
|
||||
* confirm the ongoing validity of a previously authenticated
|
||||
* <code>Authentication</code>.
|
||||
*
|
||||
* <p>
|
||||
* The implementation should throw a suitable exception if the user has
|
||||
* exceeded their maximum allowed concurrent sessions.
|
||||
* </p>
|
||||
* Called by any class that wishes to know whether the current authentication request should be permitted.
|
||||
* Generally callers will be <code>AuthenticationManager</code>s before they authenticate, but could equally
|
||||
* include <code>Filter</code>s or other interceptors that wish to confirm the ongoing validity of a previously
|
||||
* authenticated <code>Authentication</code>.<p>The implementation should throw a suitable exception if the
|
||||
* user has exceeded their maximum allowed concurrent sessions.</p>
|
||||
*
|
||||
* @param request the authentication request (never <code>null</code>)
|
||||
*
|
||||
* @throws AuthenticationException if the user has exceeded their maximum
|
||||
* allowed current sessions
|
||||
* @throws AuthenticationException if the user has exceeded their maximum allowed current sessions
|
||||
*/
|
||||
public void checkAuthenticationAllowed(Authentication request)
|
||||
throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Called by an <code>AuthenticationManager</code> when the authentication
|
||||
* was successful. An implementation is expected to register the
|
||||
* authenticated user in some sort of registry, for future concurrent
|
||||
* tracking via the {@link #checkConcurrentAuthentication(Authentication)}
|
||||
* method.
|
||||
* Called by an <code>AuthenticationManager</code> when the authentication was successful. An
|
||||
* implementation is expected to register the authenticated user in some sort of registry, for future concurrent
|
||||
* tracking via the {@link #checkConcurrentAuthentication(Authentication)} method.
|
||||
*
|
||||
* @param authentication the successfully authenticated user (never
|
||||
* <code>null</code>)
|
||||
* @param authentication the successfully authenticated user (never <code>null</code>)
|
||||
*/
|
||||
public void registerSuccessfulAuthentication(Authentication authentication);
|
||||
}
|
||||
|
||||
@@ -29,29 +29,22 @@ import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Base implementation of {@link ConcurrentSessionControllerImpl} which
|
||||
* prohibits simultaneous logins.
|
||||
*
|
||||
* <p>
|
||||
* By default uses {@link SessionRegistryImpl}, although any
|
||||
* <code>SessionRegistry</code> may be used.
|
||||
* </p>
|
||||
* Base implementation of {@link ConcurrentSessionControllerImpl} which prohibits simultaneous logins.<p>By default
|
||||
* uses {@link SessionRegistryImpl}, although any <code>SessionRegistry</code> may be used.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ConcurrentSessionControllerImpl
|
||||
implements ConcurrentSessionController, InitializingBean,
|
||||
MessageSourceAware {
|
||||
//~ Instance fields ========================================================
|
||||
public class ConcurrentSessionControllerImpl implements ConcurrentSessionController, InitializingBean,
|
||||
MessageSourceAware {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected MessageSourceAccessor messages = AcegiMessageSource
|
||||
.getAccessor();
|
||||
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
|
||||
private SessionRegistry sessionRegistry = new SessionRegistryImpl();
|
||||
private boolean exceptionIfMaximumExceeded = false;
|
||||
private int maximumSessions = 1;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(sessionRegistry, "SessionRegistry required");
|
||||
@@ -61,35 +54,27 @@ public class ConcurrentSessionControllerImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to customise behaviour when too many sessions are
|
||||
* detected.
|
||||
* Allows subclasses to customise behaviour when too many sessions are detected.
|
||||
*
|
||||
* @param sessionId the session ID of the present request
|
||||
* @param sessions either <code>null</code> or all unexpired sessions
|
||||
* associated with the principal
|
||||
* @param sessions either <code>null</code> or all unexpired sessions associated with the principal
|
||||
* @param allowableSessions DOCUMENT ME!
|
||||
* @param registry an instance of the <code>SessionRegistry</code> for
|
||||
* subclass use
|
||||
* @param registry an instance of the <code>SessionRegistry</code> for subclass use
|
||||
*
|
||||
* @throws ConcurrentLoginException DOCUMENT ME!
|
||||
*/
|
||||
protected void allowableSessionsExceeded(String sessionId,
|
||||
SessionInformation[] sessions, int allowableSessions,
|
||||
protected void allowableSessionsExceeded(String sessionId, SessionInformation[] sessions, int allowableSessions,
|
||||
SessionRegistry registry) {
|
||||
if (exceptionIfMaximumExceeded || (sessions == null)) {
|
||||
throw new ConcurrentLoginException(messages.getMessage(
|
||||
"ConcurrentSessionControllerImpl.exceededAllowed",
|
||||
new Object[] {new Integer(allowableSessions)},
|
||||
"Maximum sessions of {0} for this principal exceeded"));
|
||||
throw new ConcurrentLoginException(messages.getMessage("ConcurrentSessionControllerImpl.exceededAllowed",
|
||||
new Object[] {new Integer(allowableSessions)}, "Maximum sessions of {0} for this principal exceeded"));
|
||||
}
|
||||
|
||||
// Determine least recently used session, and mark it for invalidation
|
||||
SessionInformation leastRecentlyUsed = null;
|
||||
|
||||
for (int i = 0; i < sessions.length; i++) {
|
||||
if ((leastRecentlyUsed == null)
|
||||
|| sessions[i].getLastRequest()
|
||||
.before(leastRecentlyUsed.getLastRequest())) {
|
||||
if ((leastRecentlyUsed == null) || sessions[i].getLastRequest().before(leastRecentlyUsed.getLastRequest())) {
|
||||
leastRecentlyUsed = sessions[i];
|
||||
}
|
||||
}
|
||||
@@ -99,16 +84,12 @@ public class ConcurrentSessionControllerImpl
|
||||
|
||||
public void checkAuthenticationAllowed(Authentication request)
|
||||
throws AuthenticationException {
|
||||
Assert.notNull(request,
|
||||
"Authentication request cannot be null (violation of interface contract)");
|
||||
Assert.notNull(request, "Authentication request cannot be null (violation of interface contract)");
|
||||
|
||||
Object principal = SessionRegistryUtils
|
||||
.obtainPrincipalFromAuthentication(request);
|
||||
String sessionId = SessionRegistryUtils
|
||||
.obtainSessionIdFromAuthentication(request);
|
||||
Object principal = SessionRegistryUtils.obtainPrincipalFromAuthentication(request);
|
||||
String sessionId = SessionRegistryUtils.obtainSessionIdFromAuthentication(request);
|
||||
|
||||
SessionInformation[] sessions = sessionRegistry.getAllSessions(principal,
|
||||
false);
|
||||
SessionInformation[] sessions = sessionRegistry.getAllSessions(principal, false);
|
||||
|
||||
int sessionCount = 0;
|
||||
|
||||
@@ -121,11 +102,11 @@ public class ConcurrentSessionControllerImpl
|
||||
"getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum");
|
||||
|
||||
if (sessionCount < allowableSessions) {
|
||||
// They haven't got too many login sessions running at present
|
||||
// They haven't got too many login sessions running at present
|
||||
return;
|
||||
} else if (allowableSessions == -1) {
|
||||
// We permit unlimited logins
|
||||
return;
|
||||
// We permit unlimited logins
|
||||
return;
|
||||
} else if (sessionCount == allowableSessions) {
|
||||
// Only permit it though if this request is associated with one of the sessions
|
||||
for (int i = 0; i < sessionCount; i++) {
|
||||
@@ -135,40 +116,33 @@ public class ConcurrentSessionControllerImpl
|
||||
}
|
||||
}
|
||||
|
||||
allowableSessionsExceeded(sessionId, sessions, allowableSessions,
|
||||
sessionRegistry);
|
||||
allowableSessionsExceeded(sessionId, sessions, allowableSessions, sessionRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method intended for use by subclasses to override the maximum number of
|
||||
* sessions that are permitted for a particular authentication. The
|
||||
* default implementation simply returns the <code>maximumSessions</code>
|
||||
* value for the bean.
|
||||
* Method intended for use by subclasses to override the maximum number of sessions that are permitted for
|
||||
* a particular authentication. The default implementation simply returns the <code>maximumSessions</code> value
|
||||
* for the bean.
|
||||
*
|
||||
* @param authentication to determine the maximum sessions for
|
||||
*
|
||||
* @return either -1 meaning unlimited, or a positive integer to limit
|
||||
* (never zero)
|
||||
* @return either -1 meaning unlimited, or a positive integer to limit (never zero)
|
||||
*/
|
||||
protected int getMaximumSessionsForThisUser(Authentication authentication) {
|
||||
return maximumSessions;
|
||||
}
|
||||
|
||||
public void registerSuccessfulAuthentication(Authentication authentication) {
|
||||
Assert.notNull(authentication,
|
||||
"Authentication cannot be null (violation of interface contract)");
|
||||
Assert.notNull(authentication, "Authentication cannot be null (violation of interface contract)");
|
||||
|
||||
Object principal = SessionRegistryUtils
|
||||
.obtainPrincipalFromAuthentication(authentication);
|
||||
String sessionId = SessionRegistryUtils
|
||||
.obtainSessionIdFromAuthentication(authentication);
|
||||
Object principal = SessionRegistryUtils.obtainPrincipalFromAuthentication(authentication);
|
||||
String sessionId = SessionRegistryUtils.obtainSessionIdFromAuthentication(authentication);
|
||||
|
||||
sessionRegistry.removeSessionInformation(sessionId);
|
||||
sessionRegistry.registerNewSession(sessionId, principal);
|
||||
}
|
||||
|
||||
public void setExceptionIfMaximumExceeded(
|
||||
boolean exceptionIfMaximumExceeded) {
|
||||
public void setExceptionIfMaximumExceeded(boolean exceptionIfMaximumExceeded) {
|
||||
this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,42 +33,25 @@ import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
/**
|
||||
* Filter required by concurrent session handling package.
|
||||
*
|
||||
* <p>
|
||||
* This filter performs two functions. First, it calls {@link
|
||||
* org.acegisecurity.concurrent.SessionRegistry#refreshLastRequest(String)}
|
||||
* for each request. That way, registered sessions always have a correct "last
|
||||
* update" date/time. Second, it retrieves {@link
|
||||
* org.acegisecurity.concurrent.SessionInformation} from the
|
||||
* <code>SessionRegistry</code> for each request and checks if the session has
|
||||
* been marked as expired. If it has been marked as expired, the session is
|
||||
* invalidated. The invalidation of the session will also cause the request to
|
||||
* redirect to the URL specified, and a {@link
|
||||
* org.acegisecurity.ui.session.HttpSessionDestroyedEvent} to be published
|
||||
* via the {@link org.acegisecurity.ui.session.HttpSessionEventPublisher}
|
||||
* registered in <code>web.xml</code>.
|
||||
* </p>
|
||||
* Filter required by concurrent session handling package.<p>This filter performs two functions. First, it calls
|
||||
* {@link org.acegisecurity.concurrent.SessionRegistry#refreshLastRequest(String)} for each request. That way,
|
||||
* registered sessions always have a correct "last update" date/time. Second, it retrieves {@link
|
||||
* org.acegisecurity.concurrent.SessionInformation} from the <code>SessionRegistry</code> for each request and checks
|
||||
* if the session has been marked as expired. If it has been marked as expired, the session is invalidated. The
|
||||
* invalidation of the session will also cause the request to redirect to the URL specified, and a {@link
|
||||
* org.acegisecurity.ui.session.HttpSessionDestroyedEvent} to be published via the {@link
|
||||
* org.acegisecurity.ui.session.HttpSessionEventPublisher} registered in <code>web.xml</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ConcurrentSessionFilter implements Filter,
|
||||
InitializingBean {
|
||||
//~ Instance fields ========================================================
|
||||
public class ConcurrentSessionFilter implements Filter, InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private SessionRegistry sessionRegistry;
|
||||
private String expiredUrl;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setExpiredUrl(String expiredUrl) {
|
||||
this.expiredUrl = expiredUrl;
|
||||
}
|
||||
|
||||
public void setSessionRegistry(SessionRegistry sessionRegistry) {
|
||||
this.sessionRegistry = sessionRegistry;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(sessionRegistry, "SessionRegistry required");
|
||||
@@ -80,12 +63,10 @@ public class ConcurrentSessionFilter implements Filter,
|
||||
*/
|
||||
public void destroy() {}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
Assert.isInstanceOf(HttpServletRequest.class, request,
|
||||
"Can only process HttpServletRequest");
|
||||
Assert.isInstanceOf(HttpServletResponse.class, response,
|
||||
"Can only process HttpServletResponse");
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
Assert.isInstanceOf(HttpServletRequest.class, request, "Can only process HttpServletRequest");
|
||||
Assert.isInstanceOf(HttpServletResponse.class, response, "Can only process HttpServletResponse");
|
||||
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
@@ -93,18 +74,15 @@ public class ConcurrentSessionFilter implements Filter,
|
||||
HttpSession session = httpRequest.getSession(false);
|
||||
|
||||
if (session != null) {
|
||||
SessionInformation info = sessionRegistry.getSessionInformation(session
|
||||
.getId());
|
||||
SessionInformation info = sessionRegistry.getSessionInformation(session.getId());
|
||||
|
||||
if (info != null) {
|
||||
if (info.isExpired()) {
|
||||
// Expired - abort processing
|
||||
session.invalidate();
|
||||
|
||||
String targetUrl = httpRequest.getContextPath()
|
||||
+ expiredUrl;
|
||||
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(
|
||||
targetUrl));
|
||||
String targetUrl = httpRequest.getContextPath() + expiredUrl;
|
||||
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl));
|
||||
|
||||
return;
|
||||
} else {
|
||||
@@ -125,4 +103,12 @@ public class ConcurrentSessionFilter implements Filter,
|
||||
* @throws ServletException ignored
|
||||
*/
|
||||
public void init(FilterConfig arg0) throws ServletException {}
|
||||
|
||||
public void setExpiredUrl(String expiredUrl) {
|
||||
this.expiredUrl = expiredUrl;
|
||||
}
|
||||
|
||||
public void setSessionRegistry(SessionRegistry sessionRegistry) {
|
||||
this.sessionRegistry = sessionRegistry;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,15 +20,13 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* No-op implementation of {@link
|
||||
* org.acegisecurity.concurrent.ConcurrentSessionController}.
|
||||
* No-op implementation of {@link org.acegisecurity.concurrent.ConcurrentSessionController}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class NullConcurrentSessionController
|
||||
implements ConcurrentSessionController {
|
||||
//~ Methods ================================================================
|
||||
public class NullConcurrentSessionController implements ConcurrentSessionController {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void checkAuthenticationAllowed(Authentication request)
|
||||
throws AuthenticationException {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,20 +12,22 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.acegisecurity.concurrent;
|
||||
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Thrown by a <code>SessionRegistry</code> implementation if
|
||||
* an attempt is made to create new session information for an existing
|
||||
* sessionId. The user should firstly clear the existing session from the
|
||||
* Thrown by a <code>SessionRegistry</code> implementation if an attempt is made to create new session information
|
||||
* for an existing sessionId. The user should firstly clear the existing session from the
|
||||
* <code>ConcurrentSessionRegistry</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class SessionAlreadyUsedException extends AuthenticationException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public SessionAlreadyUsedException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ package org.acegisecurity.concurrent;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface SessionIdentifierAware {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Obtains the session ID.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,38 +21,28 @@ import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a record of a session within the Acegi Security framework.
|
||||
*
|
||||
* <p>
|
||||
* This is primarily used for concurrent session support.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Sessions have three states: active, expired, and destroyed. A session can
|
||||
* that is invalidated by <code>session.invalidate()</code> or via Servlet
|
||||
* Container management is considered "destroyed". An "expired" session, on
|
||||
* the other hand, is a session that Acegi Security wants to end because it
|
||||
* was selected for removal for some reason (generally as it was the least
|
||||
* recently used session and the maximum sessions for the user were reached).
|
||||
* An "expired" session is removed as soon as possible by a
|
||||
* <code>Filter</code>.
|
||||
* </p>
|
||||
* Represents a record of a session within the Acegi Security framework.<p>This is primarily used for concurrent
|
||||
* session support.</p>
|
||||
* <p>Sessions have three states: active, expired, and destroyed. A session can that is invalidated by
|
||||
* <code>session.invalidate()</code> or via Servlet Container management is considered "destroyed". An "expired"
|
||||
* session, on the other hand, is a session that Acegi Security wants to end because it was selected for removal for
|
||||
* some reason (generally as it was the least recently used session and the maximum sessions for the user were
|
||||
* reached). An "expired" session is removed as soon as possible by a <code>Filter</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SessionInformation {
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Date lastRequest;
|
||||
private Object principal;
|
||||
private String sessionId;
|
||||
private boolean expired = false;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public SessionInformation(Object principal, String sessionId,
|
||||
Date lastRequest) {
|
||||
public SessionInformation(Object principal, String sessionId, Date lastRequest) {
|
||||
Assert.notNull(principal, "Principal required");
|
||||
Assert.hasText(sessionId, "SessionId required");
|
||||
Assert.notNull(lastRequest, "LastRequest required");
|
||||
@@ -63,10 +53,10 @@ public class SessionInformation {
|
||||
|
||||
private SessionInformation() {}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public boolean isExpired() {
|
||||
return expired;
|
||||
public void expireNow() {
|
||||
this.expired = true;
|
||||
}
|
||||
|
||||
public Date getLastRequest() {
|
||||
@@ -81,8 +71,8 @@ public class SessionInformation {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public void expireNow() {
|
||||
this.expired = true;
|
||||
public boolean isExpired() {
|
||||
return expired;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,37 +22,30 @@ package org.acegisecurity.concurrent;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface SessionRegistry {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Obtains all the known principals in the <code>SessionRegistry</code>.
|
||||
*
|
||||
* @return each of the unique principals, which can then be presented to
|
||||
* {@link #getAllSessions(Object)}.
|
||||
* @return each of the unique principals, which can then be presented to {@link #getAllSessions(Object)}.
|
||||
*/
|
||||
public Object[] getAllPrincipals();
|
||||
|
||||
/**
|
||||
* Obtains all the known sessions for the specified principal. Sessions
|
||||
* that have been destroyed are not returned. Sessions that have expired
|
||||
* may be returned, depending on the passed argument.
|
||||
* Obtains all the known sessions for the specified principal. Sessions that have been destroyed are not
|
||||
* returned. Sessions that have expired may be returned, depending on the passed argument.
|
||||
*
|
||||
* @param principal to locate sessions for (should never be
|
||||
* <code>null</code>)
|
||||
* @param includeExpiredSessions if <code>true</code>, the returned
|
||||
* sessions will also include those that have expired for the
|
||||
* principal
|
||||
* @param principal to locate sessions for (should never be <code>null</code>)
|
||||
* @param includeExpiredSessions if <code>true</code>, the returned sessions will also include those that have
|
||||
* expired for the principal
|
||||
*
|
||||
* @return the matching sessions for this principal, or <code>null</code>
|
||||
* if none were found
|
||||
* @return the matching sessions for this principal, or <code>null</code> if none were found
|
||||
*/
|
||||
public SessionInformation[] getAllSessions(Object principal,
|
||||
boolean includeExpiredSessions);
|
||||
public SessionInformation[] getAllSessions(Object principal, boolean includeExpiredSessions);
|
||||
|
||||
/**
|
||||
* Obtains the session information for the specified
|
||||
* <code>sessionId</code>. Even expired sessions are returned (although
|
||||
* destroyed sessions are never returned).
|
||||
* Obtains the session information for the specified <code>sessionId</code>. Even expired sessions are
|
||||
* returned (although destroyed sessions are never returned).
|
||||
*
|
||||
* @param sessionId to lookup (should never be <code>null</code>)
|
||||
*
|
||||
@@ -61,24 +54,19 @@ public interface SessionRegistry {
|
||||
public SessionInformation getSessionInformation(String sessionId);
|
||||
|
||||
/**
|
||||
* Updates the given <code>sessionId</code> so its last request time is
|
||||
* equal to the present date and time. Silently returns if the given
|
||||
* <code>sessionId</code> cannot be found or the session is marked to
|
||||
* expire.
|
||||
* Updates the given <code>sessionId</code> so its last request time is equal to the present date and time.
|
||||
* Silently returns if the given <code>sessionId</code> cannot be found or the session is marked to expire.
|
||||
*
|
||||
* @param sessionId for which to update the date and time of the last
|
||||
* request (should never be <code>null</code>)
|
||||
* @param sessionId for which to update the date and time of the last request (should never be <code>null</code>)
|
||||
*/
|
||||
public void refreshLastRequest(String sessionId);
|
||||
|
||||
/**
|
||||
* Registers a new session for the specified principal. The newly
|
||||
* registered session will not be marked for expiration.
|
||||
* Registers a new session for the specified principal. The newly registered session will not be marked for
|
||||
* expiration.
|
||||
*
|
||||
* @param sessionId to associate with the principal (should never be
|
||||
* <code>null</code>)
|
||||
* @param principal to associate with the session (should never be
|
||||
* <code>null</code>)
|
||||
* @param sessionId to associate with the principal (should never be <code>null</code>)
|
||||
* @param principal to associate with the session (should never be <code>null</code>)
|
||||
*
|
||||
* @throws SessionAlreadyUsedException DOCUMENT ME!
|
||||
*/
|
||||
@@ -86,12 +74,10 @@ public interface SessionRegistry {
|
||||
throws SessionAlreadyUsedException;
|
||||
|
||||
/**
|
||||
* Deletes all the session information being maintained for the specified
|
||||
* <code>sessionId</code>. If the <code>sessionId</code> is not found, the
|
||||
* method gracefully returns.
|
||||
* Deletes all the session information being maintained for the specified <code>sessionId</code>. If the
|
||||
* <code>sessionId</code> is not found, the method gracefully returns.
|
||||
*
|
||||
* @param sessionId to delete information for (should never be
|
||||
* <code>null</code>)
|
||||
* @param sessionId to delete information for (should never be <code>null</code>)
|
||||
*/
|
||||
public void removeSessionInformation(String sessionId);
|
||||
}
|
||||
|
||||
@@ -29,12 +29,11 @@ import org.springframework.util.Assert;
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SessionRegistryUtils {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static Object obtainPrincipalFromAuthentication(Authentication auth) {
|
||||
Assert.notNull(auth, "Authentication required");
|
||||
Assert.notNull(auth.getPrincipal(),
|
||||
"Authentication.getPrincipal() required");
|
||||
Assert.notNull(auth.getPrincipal(), "Authentication.getPrincipal() required");
|
||||
|
||||
if (auth.getPrincipal() instanceof UserDetails) {
|
||||
return ((UserDetails) auth.getPrincipal()).getUsername();
|
||||
@@ -48,11 +47,8 @@ public class SessionRegistryUtils {
|
||||
Assert.notNull(auth.getDetails(), "Authentication.getDetails() required");
|
||||
Assert.isInstanceOf(SessionIdentifierAware.class, auth.getDetails());
|
||||
|
||||
String sessionId = ((SessionIdentifierAware) auth.getDetails())
|
||||
.getSessionId();
|
||||
Assert.hasText(sessionId,
|
||||
"SessionIdentifierAware did not return a Session ID ("
|
||||
+ auth.getDetails() + ")");
|
||||
String sessionId = ((SessionIdentifierAware) auth.getDetails()).getSessionId();
|
||||
Assert.hasText(sessionId, "SessionIdentifierAware did not return a Session ID (" + auth.getDetails() + ")");
|
||||
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@@ -20,24 +20,18 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A <code>static</code> field-based implementation of {@link
|
||||
* org.acegisecurity.context.SecurityContextHolderStrategy}.
|
||||
*
|
||||
* <p>
|
||||
* This means that all instances in the JVM share the same
|
||||
* <code>SecurityContext</code>. This is generally useful with rich clients,
|
||||
* such as Swing.
|
||||
* </p>
|
||||
* org.acegisecurity.context.SecurityContextHolderStrategy}.<p>This means that all instances in the JVM share the
|
||||
* same <code>SecurityContext</code>. This is generally useful with rich clients, such as Swing.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id: SecurityContextHolder.java 1324 2006-02-12 06:29:53Z benalex $
|
||||
*/
|
||||
public class GlobalSecurityContextHolderStrategy
|
||||
implements SecurityContextHolderStrategy {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class GlobalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static SecurityContext contextHolder;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void clearContext() {
|
||||
contextHolder = null;
|
||||
@@ -52,8 +46,7 @@ public class GlobalSecurityContextHolderStrategy
|
||||
}
|
||||
|
||||
public void setContext(SecurityContext context) {
|
||||
Assert.notNull(context,
|
||||
"Only non-null SecurityContext instances are permitted");
|
||||
Assert.notNull(context, "Only non-null SecurityContext instances are permitted");
|
||||
contextHolder = context;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,78 +33,43 @@ import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Populates the {@link SecurityContextHolder} with information obtained from
|
||||
* the <code>HttpSession</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The <code>HttpSession</code> will be queried to retrieve the
|
||||
* <code>SecurityContext</code> that should be stored against the
|
||||
* <code>SecurityContextHolder</code> for the duration of the web request. At
|
||||
* the end of the web request, any updates made to the
|
||||
* <code>SecurityContextHolder</code> will be persisted back to the
|
||||
* <code>HttpSession</code> by this filter.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a valid <code>SecurityContext</code> cannot be obtained from the
|
||||
* <code>HttpSession</code> for whatever reason, a fresh
|
||||
* <code>SecurityContext</code> will be created and used instead. The created
|
||||
* object will be of the instance defined by the {@link #setContext(Class)}
|
||||
* method (which defaults to {@link
|
||||
* org.acegisecurity.context.SecurityContextImpl}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* No <code>HttpSession</code> will be created by this filter if one does not
|
||||
* already exist. If at the end of the web request the
|
||||
* <code>HttpSession</code> does not exist, a <code>HttpSession</code> will
|
||||
* <b>only</b> be created if the current contents of the
|
||||
* <code>SecurityContextHolder</code> are not {@link
|
||||
* java.lang.Object#equals(java.lang.Object)} to a <code>new</code> instance
|
||||
* of {@link #setContext(Class)}. This avoids needless
|
||||
* <code>HttpSession</code> creation, but automates the storage of changes
|
||||
* made to the <code>SecurityContextHolder</code>. There is one exception to
|
||||
* this rule, that is if the {@link #forceEagerSessionCreation} property is
|
||||
* <code>true</code>, in which case sessions will always be created
|
||||
* irrespective of normal session-minimisation logic (the default is
|
||||
* <code>false</code>, as this is resource intensive and not recommended).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This filter will only execute once per request, to resolve servlet container
|
||||
* (specifically Weblogic) incompatibilities.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If for whatever reason no <code>HttpSession</code> should <b>ever</b> be
|
||||
* created (eg this filter is only being used with Basic authentication or
|
||||
* similar clients that will never present the same <code>jsessionid</code>
|
||||
* etc), the {@link #setAllowSessionCreation(boolean)} should be set to
|
||||
* <code>false</code>. Only do this if you really need to conserve server
|
||||
* memory and ensure all classes using the <code>SecurityContextHolder</code>
|
||||
* are designed to have no persistence of the <code>SecurityContext</code>
|
||||
* between web requests. Please note that if {@link
|
||||
* #forceEagerSessionCreation} is <code>true</code>, the
|
||||
* <code>allowSessionCreation</code> must also be <code>true</code> (setting
|
||||
* it to <code>false</code> will cause a startup time error).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This filter MUST be executed BEFORE any authentication processing
|
||||
* mechanisms. Authentication processing mechanisms (eg BASIC, CAS processing
|
||||
* filters etc) expect the <code>SecurityContextHolder</code> to contain a
|
||||
* valid <code>SecurityContext</code> by the time they execute.
|
||||
* </p>
|
||||
* <p>Populates the {@link SecurityContextHolder} with information obtained from the <code>HttpSession</code>.</p>
|
||||
* <p>The <code>HttpSession</code> will be queried to retrieve the <code>SecurityContext</code> that should be
|
||||
* stored against the <code>SecurityContextHolder</code> for the duration of the web request. At the end of the web
|
||||
* request, any updates made to the <code>SecurityContextHolder</code> will be persisted back to the
|
||||
* <code>HttpSession</code> by this filter.</p>
|
||||
* <p>If a valid <code>SecurityContext</code> cannot be obtained from the <code>HttpSession</code> for whatever
|
||||
* reason, a fresh <code>SecurityContext</code> will be created and used instead. The created object will be of the
|
||||
* instance defined by the {@link #setContext(Class)} method (which defaults to {@link
|
||||
* org.acegisecurity.context.SecurityContextImpl}.</p>
|
||||
* <p>No <code>HttpSession</code> will be created by this filter if one does not already exist. If at the end of
|
||||
* the web request the <code>HttpSession</code> does not exist, a <code>HttpSession</code> will <b>only</b> be created
|
||||
* if the current contents of the <code>SecurityContextHolder</code> are not {@link
|
||||
* java.lang.Object#equals(java.lang.Object)} to a <code>new</code> instance of {@link #setContext(Class)}. This
|
||||
* avoids needless <code>HttpSession</code> creation, but automates the storage of changes made to the
|
||||
* <code>SecurityContextHolder</code>. There is one exception to this rule, that is if the {@link
|
||||
* #forceEagerSessionCreation} property is <code>true</code>, in which case sessions will always be created
|
||||
* irrespective of normal session-minimisation logic (the default is <code>false</code>, as this is resource intensive
|
||||
* and not recommended).</p>
|
||||
* <p>This filter will only execute once per request, to resolve servlet container (specifically Weblogic)
|
||||
* incompatibilities.</p>
|
||||
* <p>If for whatever reason no <code>HttpSession</code> should <b>ever</b> be created (eg this filter is only
|
||||
* being used with Basic authentication or similar clients that will never present the same <code>jsessionid</code>
|
||||
* etc), the {@link #setAllowSessionCreation(boolean)} should be set to <code>false</code>. Only do this if you really
|
||||
* need to conserve server memory and ensure all classes using the <code>SecurityContextHolder</code> are designed to
|
||||
* have no persistence of the <code>SecurityContext</code> between web requests. Please note that if {@link
|
||||
* #forceEagerSessionCreation} is <code>true</code>, the <code>allowSessionCreation</code> must also be
|
||||
* <code>true</code> (setting it to <code>false</code> will cause a startup time error).</p>
|
||||
* <p>This filter MUST be executed BEFORE any authentication processing mechanisms. Authentication processing
|
||||
* mechanisms (eg BASIC, CAS processing filters etc) expect the <code>SecurityContextHolder</code> to contain a valid
|
||||
* <code>SecurityContext</code> by the time they execute.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Patrick Burleson
|
||||
* @version $Id$
|
||||
*/
|
||||
public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
Filter {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class HttpSessionContextIntegrationFilter implements InitializingBean, Filter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =============================================
|
||||
@@ -112,7 +77,7 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
private static final String FILTER_APPLIED = "__acegi_session_integration_filter_applied";
|
||||
public static final String ACEGI_SECURITY_CONTEXT_KEY = "ACEGI_SECURITY_CONTEXT";
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
// ~ Instance fields
|
||||
// ========================================================
|
||||
@@ -120,43 +85,35 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
private Object contextObject;
|
||||
|
||||
/**
|
||||
* Indicates if this filter can create a <code>HttpSession</code> if needed
|
||||
* (sessions are always created sparingly, but setting this value to
|
||||
* <code>false</code> will prohibit sessions from ever being created).
|
||||
* Defaults to <code>true</code>. Do not set to <code>false</code> if you
|
||||
* are have set {@link #forceEagerSessionCreation} to <code>true</code>,
|
||||
* as the properties would be in conflict.
|
||||
* Indicates if this filter can create a <code>HttpSession</code> if needed (sessions are always created
|
||||
* sparingly, but setting this value to <code>false</code> will prohibit sessions from ever being created).
|
||||
* Defaults to <code>true</code>. Do not set to <code>false</code> if you are have set {@link
|
||||
* #forceEagerSessionCreation} to <code>true</code>, as the properties would be in conflict.
|
||||
*/
|
||||
private boolean allowSessionCreation = true;
|
||||
|
||||
/**
|
||||
* Indicates if this filter is required to create a
|
||||
* <code>HttpSession</code> for every request before proceeding through
|
||||
* the filter chain, even if the <code>HttpSession</code> would not
|
||||
* ordinarily have been created. By default this is <code>false</code>,
|
||||
* which is entirely appropriate for most circumstances as you do not want
|
||||
* a <code>HttpSession</code> created unless the filter actually needs
|
||||
* one. It is envisaged the main situation in which this property would be
|
||||
* set to <code>true</code> is if using other filters that depend on a
|
||||
* <code>HttpSession</code> already existing, such as those which need to
|
||||
* obtain a session ID. This is only required in specialised cases, so
|
||||
* leave it set to <code>false</code> unless you have an actual
|
||||
* requirement and are conscious of the session creation overhead.
|
||||
* Indicates if this filter is required to create a <code>HttpSession</code> for every request before
|
||||
* proceeding through the filter chain, even if the <code>HttpSession</code> would not ordinarily have been
|
||||
* created. By default this is <code>false</code>, which is entirely appropriate for most circumstances as you do
|
||||
* not want a <code>HttpSession</code> created unless the filter actually needs one. It is envisaged the main
|
||||
* situation in which this property would be set to <code>true</code> is if using other filters that depend on a
|
||||
* <code>HttpSession</code> already existing, such as those which need to obtain a session ID. This is only
|
||||
* required in specialised cases, so leave it set to <code>false</code> unless you have an actual requirement and
|
||||
* are conscious of the session creation overhead.
|
||||
*/
|
||||
private boolean forceEagerSessionCreation = false;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if ((this.context == null)
|
||||
|| (!SecurityContext.class.isAssignableFrom(this.context))) {
|
||||
if ((this.context == null) || (!SecurityContext.class.isAssignableFrom(this.context))) {
|
||||
throw new IllegalArgumentException(
|
||||
"context must be defined and implement SecurityContext (typically use org.acegisecurity.context.SecurityContextImpl; existing class is "
|
||||
+ this.context + ")");
|
||||
}
|
||||
|
||||
if ((forceEagerSessionCreation == true)
|
||||
&& (allowSessionCreation == false)) {
|
||||
if ((forceEagerSessionCreation == true) && (allowSessionCreation == false)) {
|
||||
throw new IllegalArgumentException(
|
||||
"If using forceEagerSessionCreation, you must set allowSessionCreation to also be true");
|
||||
}
|
||||
@@ -169,8 +126,8 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
*/
|
||||
public void destroy() {}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) {
|
||||
// ensure that filter is only applied once per request
|
||||
chain.doFilter(request, response);
|
||||
@@ -202,8 +159,7 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject);
|
||||
} else {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
"ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
|
||||
logger.warn("ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
|
||||
+ contextFromSessionObject
|
||||
+ "'; are you improperly modifying the HttpSession directly (you should always use SecurityContextHolder) or using the HttpSession attribute reserved for this class? - new SecurityContext instance associated with SecurityContextHolder");
|
||||
}
|
||||
@@ -233,8 +189,7 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
httpSession = null;
|
||||
|
||||
// Proceed with chain
|
||||
int contextWhenChainProceeded = SecurityContextHolder.getContext()
|
||||
.hashCode();
|
||||
int contextWhenChainProceeded = SecurityContextHolder.getContext().hashCode();
|
||||
|
||||
try {
|
||||
chain.doFilter(request, response);
|
||||
@@ -257,23 +212,19 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
}
|
||||
|
||||
// Generate a HttpSession only if we need to
|
||||
if ((httpSession == null)
|
||||
&& !httpSessionExistedAtStartOfRequest) {
|
||||
if ((httpSession == null) && !httpSessionExistedAtStartOfRequest) {
|
||||
if (!allowSessionCreation) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"The HttpSession is currently null, and the HttpSessionContextIntegrationFilter is prohibited from creating a HttpSession (because the allowSessionCreation property is false) - SecurityContext thus not stored for next request");
|
||||
}
|
||||
} else if (!contextObject.equals(
|
||||
SecurityContextHolder.getContext())) {
|
||||
} else if (!contextObject.equals(SecurityContextHolder.getContext())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"HttpSession being created as SecurityContextHolder contents are non-default");
|
||||
logger.debug("HttpSession being created as SecurityContextHolder contents are non-default");
|
||||
}
|
||||
|
||||
try {
|
||||
httpSession = ((HttpServletRequest) request)
|
||||
.getSession(true);
|
||||
httpSession = ((HttpServletRequest) request).getSession(true);
|
||||
} catch (IllegalStateException ignored) {}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -291,12 +242,11 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
// SEC-37)
|
||||
if ((httpSession != null)
|
||||
&& (SecurityContextHolder.getContext().hashCode() != contextWhenChainProceeded)) {
|
||||
httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY,
|
||||
SecurityContextHolder.getContext());
|
||||
httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("SecurityContext stored to HttpSession: '"
|
||||
+ SecurityContextHolder.getContext() + "'");
|
||||
logger.debug("SecurityContext stored to HttpSession: '" + SecurityContextHolder.getContext()
|
||||
+ "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,8 +254,7 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean,
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"SecurityContextHolder set to new context, as request processing completed");
|
||||
logger.debug("SecurityContextHolder set to new context, as request processing completed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@ import org.springframework.util.Assert;
|
||||
* @see org.acegisecurity.context.HttpSessionContextIntegrationFilter
|
||||
*/
|
||||
public class InheritableThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static ThreadLocal contextHolder = new InheritableThreadLocal();
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void clearContext() {
|
||||
contextHolder.set(null);
|
||||
@@ -48,8 +48,7 @@ public class InheritableThreadLocalSecurityContextHolderStrategy implements Secu
|
||||
}
|
||||
|
||||
public void setContext(SecurityContext context) {
|
||||
Assert.notNull(context,
|
||||
"Only non-null SecurityContext instances are permitted");
|
||||
Assert.notNull(context, "Only non-null SecurityContext instances are permitted");
|
||||
contextHolder.set(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,24 +32,20 @@ import java.io.Serializable;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface SecurityContext extends Serializable {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Changes the currently authenticated principal, or removes the
|
||||
* authentication information.
|
||||
* Obtains the currently authenticated principal, or an authentication request token.
|
||||
*
|
||||
* @param authentication the new <code>Authentication</code> token, or
|
||||
* <code>null</code> if no further authentication information
|
||||
* should be stored
|
||||
*/
|
||||
public void setAuthentication(Authentication authentication);
|
||||
|
||||
/**
|
||||
* Obtains the currently authenticated principal, or an authentication
|
||||
* request token.
|
||||
*
|
||||
* @return the <code>Authentication</code> or <code>null</code> if no
|
||||
* authentication information is available
|
||||
* @return the <code>Authentication</code> or <code>null</code> if no authentication information is available
|
||||
*/
|
||||
public Authentication getAuthentication();
|
||||
|
||||
/**
|
||||
* Changes the currently authenticated principal, or removes the authentication information.
|
||||
*
|
||||
* @param authentication the new <code>Authentication</code> token, or <code>null</code> if no further
|
||||
* authentication information should be stored
|
||||
*/
|
||||
public void setAuthentication(Authentication authentication);
|
||||
}
|
||||
|
||||
@@ -21,36 +21,20 @@ import java.lang.reflect.Constructor;
|
||||
|
||||
|
||||
/**
|
||||
* Associates a given {@link SecurityContext} with the current execution
|
||||
* thread.
|
||||
*
|
||||
* <p>
|
||||
* This class provides a series of static methods that delegate to an instance
|
||||
* of {@link org.acegisecurity.context.SecurityContextHolderStrategy}. The
|
||||
* purpose of the class is to provide a convenient way to specify the strategy
|
||||
* that should be used for a given JVM. This is a JVM-wide setting, since
|
||||
* everything in this class is <code>static</code> to facilitate ease of use
|
||||
* in calling code.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* To specify which strategy should be used, you must provide a mode setting. A
|
||||
* mode setting is one of the three valid <code>MODE_</code> settings defined
|
||||
* as <code>static final</code> fields, or a fully qualified classname to a
|
||||
* concrete implementation of {@link
|
||||
* org.acegisecurity.context.SecurityContextHolderStrategy} that provides a
|
||||
* public no-argument constructor.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* There are two ways to specify the desired mode <code>String</code>. The
|
||||
* first is to specify it via the system property keyed on {@link
|
||||
* #SYSTEM_PROPERTY}. The second is to call {@link #setStrategyName(String)}
|
||||
* before using the class. If neither approach is used, the class will default
|
||||
* to using {@link #MODE_THREADLOCAL}, which is backwards compatible, has
|
||||
* fewer JVM incompatibilities and is appropriate on servers (whereas {@link
|
||||
* #MODE_GLOBAL} is not).
|
||||
* </p>
|
||||
* Associates a given {@link SecurityContext} with the current execution thread.<p>This class provides a series of
|
||||
* static methods that delegate to an instance of {@link org.acegisecurity.context.SecurityContextHolderStrategy}. The
|
||||
* purpose of the class is to provide a convenient way to specify the strategy that should be used for a given JVM.
|
||||
* This is a JVM-wide setting, since everything in this class is <code>static</code> to facilitate ease of use in
|
||||
* calling code.</p>
|
||||
* <p>To specify which strategy should be used, you must provide a mode setting. A mode setting is one of the
|
||||
* three valid <code>MODE_</code> settings defined as <code>static final</code> fields, or a fully qualified classname
|
||||
* to a concrete implementation of {@link org.acegisecurity.context.SecurityContextHolderStrategy} that provides a
|
||||
* public no-argument constructor.</p>
|
||||
* <p>There are two ways to specify the desired mode <code>String</code>. The first is to specify it via the
|
||||
* system property keyed on {@link #SYSTEM_PROPERTY}. The second is to call {@link #setStrategyName(String)} before
|
||||
* using the class. If neither approach is used, the class will default to using {@link #MODE_THREADLOCAL}, which is
|
||||
* backwards compatible, has fewer JVM incompatibilities and is appropriate on servers (whereas {@link #MODE_GLOBAL}
|
||||
* is not).</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
@@ -58,7 +42,7 @@ import java.lang.reflect.Constructor;
|
||||
* @see org.acegisecurity.context.HttpSessionContextIntegrationFilter
|
||||
*/
|
||||
public class SecurityContextHolder {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";
|
||||
public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";
|
||||
@@ -68,7 +52,7 @@ public class SecurityContextHolder {
|
||||
private static Constructor customStrategy;
|
||||
private static SecurityContextHolderStrategy strategy;
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Explicitly clears the context value from the current thread.
|
||||
@@ -109,8 +93,7 @@ public class SecurityContextHolder {
|
||||
customStrategy = clazz.getConstructor(new Class[] {});
|
||||
}
|
||||
|
||||
strategy = (SecurityContextHolderStrategy) customStrategy
|
||||
.newInstance(new Object[] {});
|
||||
strategy = (SecurityContextHolderStrategy) customStrategy.newInstance(new Object[] {});
|
||||
} catch (Exception ex) {
|
||||
ReflectionUtils.handleReflectionException(ex);
|
||||
}
|
||||
@@ -118,11 +101,9 @@ public class SecurityContextHolder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates a new <code>SecurityContext</code> with the current thread of
|
||||
* execution.
|
||||
* Associates a new <code>SecurityContext</code> with the current thread of execution.
|
||||
*
|
||||
* @param context the new <code>SecurityContext</code> (may not be
|
||||
* <code>null</code>)
|
||||
* @param context the new <code>SecurityContext</code> (may not be <code>null</code>)
|
||||
*/
|
||||
public static void setContext(SecurityContext context) {
|
||||
initialize();
|
||||
@@ -130,12 +111,10 @@ public class SecurityContextHolder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the preferred strategy. Do <em>NOT</em> call this method more
|
||||
* than once for a given JVM, as it will reinitialize the strategy and
|
||||
* adversely affect any existing threads using the old strategy.
|
||||
* Changes the preferred strategy. Do <em>NOT</em> call this method more than once for a given JVM, as it
|
||||
* will reinitialize the strategy and adversely affect any existing threads using the old strategy.
|
||||
*
|
||||
* @param strategyName the fully qualified classname of the strategy that
|
||||
* should be used.
|
||||
* @param strategyName the fully qualified classname of the strategy that should be used.
|
||||
*/
|
||||
public static void setStrategyName(String strategyName) {
|
||||
SecurityContextHolder.strategyName = strategyName;
|
||||
|
||||
@@ -27,7 +27,7 @@ package org.acegisecurity.context;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface SecurityContextHolderStrategy {
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Clears the current context.
|
||||
@@ -37,18 +37,15 @@ public interface SecurityContextHolderStrategy {
|
||||
/**
|
||||
* Obtains the current context.
|
||||
*
|
||||
* @return a context (never <code>null</code> - create a default
|
||||
* implementation if necessary)
|
||||
* @return a context (never <code>null</code> - create a default implementation if necessary)
|
||||
*/
|
||||
public SecurityContext getContext();
|
||||
|
||||
/**
|
||||
* Sets the current context.
|
||||
*
|
||||
* @param context to the new argument (should never be <code>null</code>,
|
||||
* although implementations must check if <code>null</code> has
|
||||
* been passed and throw an <code>IllegalArgumentException</code>
|
||||
* in such cases)
|
||||
* @param context to the new argument (should never be <code>null</code>, although implementations must check if
|
||||
* <code>null</code> has been passed and throw an <code>IllegalArgumentException</code> in such cases)
|
||||
*/
|
||||
public void setContext(SecurityContext context);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,49 +12,57 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.acegisecurity.context;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
|
||||
|
||||
/**
|
||||
* Base implementation of {@link SecurityContext}.
|
||||
*
|
||||
* <p>
|
||||
* Used by default by {@link SecurityContextHolder} and {@link HttpSessionContextIntegrationFilter}.
|
||||
* </p>
|
||||
* Base implementation of {@link SecurityContext}.<p>Used by default by {@link SecurityContextHolder} and {@link
|
||||
* HttpSessionContextIntegrationFilter}.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SecurityContextImpl implements SecurityContext {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Authentication authentication;
|
||||
|
||||
public void setAuthentication(Authentication authentication) {
|
||||
this.authentication = authentication;
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof SecurityContextImpl) {
|
||||
SecurityContextImpl test = (SecurityContextImpl) obj;
|
||||
|
||||
if ((this.getAuthentication() == null) && (test.getAuthentication() == null)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((this.getAuthentication() != null) && (test.getAuthentication() != null)
|
||||
&& this.getAuthentication().equals(test.getAuthentication())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Authentication getAuthentication() {
|
||||
return authentication;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof SecurityContextImpl) {
|
||||
SecurityContextImpl test = (SecurityContextImpl) obj;
|
||||
|
||||
if ((this.getAuthentication() == null) &&
|
||||
(test.getAuthentication() == null)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((this.getAuthentication() != null) &&
|
||||
(test.getAuthentication() != null) &&
|
||||
this.getAuthentication().equals(test.getAuthentication())) {
|
||||
return true;
|
||||
}
|
||||
public int hashCode() {
|
||||
if (this.authentication == null) {
|
||||
return -1;
|
||||
} else {
|
||||
return this.authentication.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
public void setAuthentication(Authentication authentication) {
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@@ -69,12 +77,4 @@ public class SecurityContextImpl implements SecurityContext {
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (this.authentication == null) {
|
||||
return -1;
|
||||
} else {
|
||||
return this.authentication.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@ import org.springframework.util.Assert;
|
||||
* @see org.acegisecurity.context.HttpSessionContextIntegrationFilter
|
||||
*/
|
||||
public class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static ThreadLocal contextHolder = new ThreadLocal();
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void clearContext() {
|
||||
contextHolder.set(null);
|
||||
@@ -48,8 +48,7 @@ public class ThreadLocalSecurityContextHolderStrategy implements SecurityContext
|
||||
}
|
||||
|
||||
public void setContext(SecurityContext context) {
|
||||
Assert.notNull(context,
|
||||
"Only non-null SecurityContext instances are permitted");
|
||||
Assert.notNull(context, "Only non-null SecurityContext instances are permitted");
|
||||
contextHolder.set(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,24 +32,21 @@ import java.net.HttpURLConnection;
|
||||
|
||||
|
||||
/**
|
||||
* Adds BASIC authentication support to
|
||||
* <code>SimpleHttpInvokerRequestExecutor</code>.
|
||||
* Adds BASIC authentication support to <code>SimpleHttpInvokerRequestExecutor</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationSimpleHttpInvokerRequestExecutor
|
||||
extends SimpleHttpInvokerRequestExecutor {
|
||||
//~ Static fields/initializers =============================================
|
||||
public class AuthenticationSimpleHttpInvokerRequestExecutor extends SimpleHttpInvokerRequestExecutor {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AuthenticationSimpleHttpInvokerRequestExecutor.class);
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Provided so subclasses can perform additional configuration if required
|
||||
* (eg set additional request headers for non-security related information
|
||||
* etc).
|
||||
* Provided so subclasses can perform additional configuration if required (eg set additional request
|
||||
* headers for non-security related information etc).
|
||||
*
|
||||
* @param con the HTTP connection to prepare
|
||||
* @param contentLength the length of the content to send
|
||||
@@ -60,46 +57,30 @@ public class AuthenticationSimpleHttpInvokerRequestExecutor
|
||||
throws IOException {}
|
||||
|
||||
/**
|
||||
* Called every time a HTTP invocation is made.
|
||||
*
|
||||
* <p>
|
||||
* Simply allows the parent to setup the connection, and then adds an
|
||||
* <code>Authorization</code> HTTP header property that will be used for
|
||||
* BASIC authentication.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The <code>SecurityContextHolder</code> is used to obtain the relevant
|
||||
* principal and credentials.
|
||||
* </p>
|
||||
* Called every time a HTTP invocation is made.<p>Simply allows the parent to setup the connection, and
|
||||
* then adds an <code>Authorization</code> HTTP header property that will be used for BASIC authentication.</p>
|
||||
* <p>The <code>SecurityContextHolder</code> is used to obtain the relevant principal and credentials.</p>
|
||||
*
|
||||
* @param con the HTTP connection to prepare
|
||||
* @param contentLength the length of the content to send
|
||||
*
|
||||
* @throws IOException if thrown by HttpURLConnection methods
|
||||
* @throws AuthenticationCredentialsNotFoundException if the
|
||||
* <code>SecurityContextHolder</code> does not contain a valid
|
||||
* <code>Authentication</code> with both its
|
||||
* <code>principal</code> and <code>credentials</code> not
|
||||
* @throws AuthenticationCredentialsNotFoundException if the <code>SecurityContextHolder</code> does not contain a
|
||||
* valid <code>Authentication</code> with both its <code>principal</code> and <code>credentials</code> not
|
||||
* <code>null</code>
|
||||
*/
|
||||
protected void prepareConnection(HttpURLConnection con, int contentLength)
|
||||
throws IOException, AuthenticationCredentialsNotFoundException {
|
||||
super.prepareConnection(con, contentLength);
|
||||
|
||||
Authentication auth = SecurityContextHolder.getContext()
|
||||
.getAuthentication();
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if ((auth != null) && (auth.getName() != null)
|
||||
&& (auth.getCredentials() != null)) {
|
||||
String base64 = auth.getName() + ":"
|
||||
+ auth.getCredentials().toString();
|
||||
con.setRequestProperty("Authorization",
|
||||
"Basic " + new String(Base64.encodeBase64(base64.getBytes())));
|
||||
if ((auth != null) && (auth.getName() != null) && (auth.getCredentials() != null)) {
|
||||
String base64 = auth.getName() + ":" + auth.getCredentials().toString();
|
||||
con.setRequestProperty("Authorization", "Basic " + new String(Base64.encodeBase64(base64.getBytes())));
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"HttpInvocation now presenting via BASIC authentication SecurityContextHolder-derived: "
|
||||
logger.debug("HttpInvocation now presenting via BASIC authentication SecurityContextHolder-derived: "
|
||||
+ auth.toString());
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -29,39 +29,32 @@ import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
|
||||
/**
|
||||
* The actual <code>RemoteInvocation</code> that is passed from the client to
|
||||
* the server, which contains the contents of {@link SecurityContextHolder},
|
||||
* being a {@link SecurityContext} object.
|
||||
*
|
||||
* <p>
|
||||
* When constructed on the client via {@link
|
||||
* org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory},
|
||||
* the contents of the <code>SecurityContext</code> are stored inside the
|
||||
* object. The object is then passed to the server that is processing the
|
||||
* remote invocation. Upon the server invoking the remote invocation, it will
|
||||
* retrieve the passed contents of the <code>SecurityContextHolder</code> and
|
||||
* set them to the server-side <code>SecurityContextHolder</code> whilst the
|
||||
* target object is invoked. When the target invocation has been completed,
|
||||
* the server-side <code>SecurityContextHolder</code> will be reset to a new
|
||||
* instance of <code>SecurityContextImpl</code>.
|
||||
* </p>
|
||||
* The actual <code>RemoteInvocation</code> that is passed from the client to the server, which contains the
|
||||
* contents of {@link SecurityContextHolder}, being a {@link SecurityContext} object.<p>When constructed on the
|
||||
* client via {@link org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory}, the contents of the
|
||||
* <code>SecurityContext</code> are stored inside the object. The object is then passed to the server that is
|
||||
* processing the remote invocation. Upon the server invoking the remote invocation, it will retrieve the passed
|
||||
* contents of the <code>SecurityContextHolder</code> and set them to the server-side
|
||||
* <code>SecurityContextHolder</code> whilst the target object is invoked. When the target invocation has been
|
||||
* completed, the server-side <code>SecurityContextHolder</code> will be reset to a new instance of
|
||||
* <code>SecurityContextImpl</code>.</p>
|
||||
*
|
||||
* @author James Monaghan
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ContextPropagatingRemoteInvocation extends RemoteInvocation {
|
||||
//~ Static fields/initializers =============================================
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ContextPropagatingRemoteInvocation.class);
|
||||
|
||||
//~ Instance fields ========================================================
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private SecurityContext securityContext;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs the object, storing the value of the client-side
|
||||
* <code>SecurityContextHolder</code> inside the object.
|
||||
*
|
||||
@@ -72,24 +65,18 @@ public class ContextPropagatingRemoteInvocation extends RemoteInvocation {
|
||||
securityContext = SecurityContextHolder.getContext();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("RemoteInvocation now has SecurityContext: "
|
||||
+ securityContext);
|
||||
logger.debug("RemoteInvocation now has SecurityContext: " + securityContext);
|
||||
}
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Invoked on the server-side as described in the class JavaDocs.
|
||||
*
|
||||
* <p>
|
||||
* Invocations will always have their {@link
|
||||
* org.acegisecurity.Authentication#setAuthenticated(boolean)} set to
|
||||
* <code>false</code>, which is guaranteed to always be accepted by
|
||||
* <code>Authentication</code> implementations. This ensures that even
|
||||
* remotely authenticated <code>Authentication</code>s will be untrusted
|
||||
* by the server-side, which is an appropriate security measure.
|
||||
* </p>
|
||||
* Invoked on the server-side as described in the class JavaDocs.<p>Invocations will always have their
|
||||
* {@link org.acegisecurity.Authentication#setAuthenticated(boolean)} set to <code>false</code>, which is
|
||||
* guaranteed to always be accepted by <code>Authentication</code> implementations. This ensures that even
|
||||
* remotely authenticated <code>Authentication</code>s will be untrusted by the server-side, which is an
|
||||
* appropriate security measure.</p>
|
||||
*
|
||||
* @param targetObject the target object to apply the invocation to
|
||||
*
|
||||
@@ -97,23 +84,19 @@ public class ContextPropagatingRemoteInvocation extends RemoteInvocation {
|
||||
*
|
||||
* @throws NoSuchMethodException if the method name could not be resolved
|
||||
* @throws IllegalAccessException if the method could not be accessed
|
||||
* @throws InvocationTargetException if the method invocation resulted in
|
||||
* an exception
|
||||
* @throws InvocationTargetException if the method invocation resulted in an exception
|
||||
*/
|
||||
public Object invoke(Object targetObject)
|
||||
throws NoSuchMethodException, IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
|
||||
SecurityContextHolder.setContext(securityContext);
|
||||
|
||||
if ((SecurityContextHolder.getContext() != null)
|
||||
&& (SecurityContextHolder.getContext().getAuthentication() != null)) {
|
||||
SecurityContextHolder.getContext().getAuthentication()
|
||||
.setAuthenticated(false);
|
||||
SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Set SecurityContextHolder to contain: "
|
||||
+ securityContext);
|
||||
logger.debug("Set SecurityContextHolder to contain: " + securityContext);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -122,8 +105,7 @@ public class ContextPropagatingRemoteInvocation extends RemoteInvocation {
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Set SecurityContext to new instance of SecurityContextImpl");
|
||||
logger.debug("Set SecurityContext to new instance of SecurityContextImpl");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,25 +22,18 @@ import org.springframework.remoting.support.RemoteInvocationFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Called by a client-side instance of
|
||||
* <code>org.springframework.remoting.rmi.RmiProxyFactoryBean</code> when it
|
||||
* wishes to create a remote invocation.
|
||||
*
|
||||
* <P>
|
||||
* Set an instance of this bean against the above class'
|
||||
* <code>remoteInvocationFactory</code> property.
|
||||
* </p>
|
||||
* Called by a client-side instance of <code>org.springframework.remoting.rmi.RmiProxyFactoryBean</code> when it
|
||||
* wishes to create a remote invocation.<P>Set an instance of this bean against the above class'
|
||||
* <code>remoteInvocationFactory</code> property.</p>
|
||||
*
|
||||
* @author James Monaghan
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ContextPropagatingRemoteInvocationFactory
|
||||
implements RemoteInvocationFactory {
|
||||
//~ Methods ================================================================
|
||||
public class ContextPropagatingRemoteInvocationFactory implements RemoteInvocationFactory {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public RemoteInvocation createRemoteInvocation(
|
||||
MethodInvocation methodInvocation) {
|
||||
public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
|
||||
return new ContextPropagatingRemoteInvocation(methodInvocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,28 +21,24 @@ import org.springframework.context.ApplicationEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Represents an application authentication event.
|
||||
*
|
||||
* <P>
|
||||
* The <code>ApplicationEvent</code>'s <code>source</code> will be the
|
||||
* <code>Authentication</code> object.
|
||||
* </p>
|
||||
* Represents an application authentication event.<P>The <code>ApplicationEvent</code>'s <code>source</code> will
|
||||
* be the <code>Authentication</code> object.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractAuthenticationEvent extends ApplicationEvent {
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AbstractAuthenticationEvent(Authentication authentication) {
|
||||
super(authentication);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Getters for the <code>Authentication</code> request that caused the
|
||||
* event. Also available from <code>super.getSource()</code>.
|
||||
* Getters for the <code>Authentication</code> request that caused the event. Also available from
|
||||
* <code>super.getSource()</code>.
|
||||
*
|
||||
* @return the authentication request
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,28 +22,25 @@ import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract application event which indicates authentication failure for some
|
||||
* reason.
|
||||
* Abstract application event which indicates authentication failure for some reason.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractAuthenticationFailureEvent
|
||||
extends AbstractAuthenticationEvent {
|
||||
//~ Instance fields ========================================================
|
||||
public abstract class AbstractAuthenticationFailureEvent extends AbstractAuthenticationEvent {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationException exception;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AbstractAuthenticationFailureEvent(Authentication authentication,
|
||||
AuthenticationException exception) {
|
||||
public AbstractAuthenticationFailureEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication);
|
||||
Assert.notNull(exception, "AuthenticationException is required");
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public AuthenticationException getException() {
|
||||
return exception;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to invalid
|
||||
* credentials being presented.
|
||||
* Application event which indicates authentication failure due to invalid credentials being presented.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureBadCredentialsEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureBadCredentialsEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureBadCredentialsEvent(
|
||||
Authentication authentication, AuthenticationException exception) {
|
||||
public AuthenticationFailureBadCredentialsEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,18 +20,16 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to the user
|
||||
* attempting to login to too many concurrent sessions.
|
||||
* Application event which indicates authentication failure due to the user attempting to login to too many
|
||||
* concurrent sessions.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureConcurrentLoginEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureConcurrentLoginEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureConcurrentLoginEvent(
|
||||
Authentication authentication, AuthenticationException exception) {
|
||||
public AuthenticationFailureConcurrentLoginEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to the user's
|
||||
* credentials having expired.
|
||||
* Application event which indicates authentication failure due to the user's credentials having expired.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureCredentialsExpiredEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureCredentialsExpiredEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureCredentialsExpiredEvent(
|
||||
Authentication authentication, AuthenticationException exception) {
|
||||
public AuthenticationFailureCredentialsExpiredEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to the user's
|
||||
* account being disabled.
|
||||
* Application event which indicates authentication failure due to the user's account being disabled.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureDisabledEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureDisabledEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureDisabledEvent(Authentication authentication,
|
||||
AuthenticationException exception) {
|
||||
public AuthenticationFailureDisabledEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to the user's
|
||||
* account having expired.
|
||||
* Application event which indicates authentication failure due to the user's account having expired.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureExpiredEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureExpiredEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureExpiredEvent(Authentication authentication,
|
||||
AuthenticationException exception) {
|
||||
public AuthenticationFailureExpiredEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to the user's
|
||||
* account having been locked.
|
||||
* Application event which indicates authentication failure due to the user's account having been locked.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureLockedEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureLockedEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureLockedEvent(Authentication authentication,
|
||||
AuthenticationException exception) {
|
||||
public AuthenticationFailureLockedEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,19 +20,16 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to there being
|
||||
* no registered <code>AuthenticationProvider</code> that can process the
|
||||
* request.
|
||||
* Application event which indicates authentication failure due to there being no registered
|
||||
* <code>AuthenticationProvider</code> that can process the request.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureProviderNotFoundEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureProviderNotFoundEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureProviderNotFoundEvent(
|
||||
Authentication authentication, AuthenticationException exception) {
|
||||
public AuthenticationFailureProviderNotFoundEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,18 +20,16 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to the CAS
|
||||
* user's ticket being generated by an untrusted proxy.
|
||||
* Application event which indicates authentication failure due to the CAS user's ticket being generated by an
|
||||
* untrusted proxy.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureProxyUntrustedEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureProxyUntrustedEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureProxyUntrustedEvent(
|
||||
Authentication authentication, AuthenticationException exception) {
|
||||
public AuthenticationFailureProxyUntrustedEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,18 +20,16 @@ import org.acegisecurity.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to there being
|
||||
* a problem internal to the <code>AuthenticationManager</code>.
|
||||
* Application event which indicates authentication failure due to there being a problem internal to the
|
||||
* <code>AuthenticationManager</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureServiceExceptionEvent
|
||||
extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===========================================================
|
||||
public class AuthenticationFailureServiceExceptionEvent extends AbstractAuthenticationFailureEvent {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationFailureServiceExceptionEvent(
|
||||
Authentication authentication, AuthenticationException exception) {
|
||||
public AuthenticationFailureServiceExceptionEvent(Authentication authentication, AuthenticationException exception) {
|
||||
super(authentication, exception);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user