implemented unit tests for portlet support
This commit is contained in:
@@ -34,7 +34,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <p>Processes a JSR-168 Portlet authentication request. The request will typically
|
||||
* <p>Processes a JSR 168 Portlet authentication request. The request will typically
|
||||
* originate from {@link org.acegisecurity.ui.portlet.PortletProcessingInterceptor}.</p>
|
||||
*
|
||||
* <p>Be aware that this provider is trusting the portal and portlet container to handle
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.providers.AbstractAuthenticationToken;
|
||||
|
||||
/**
|
||||
* <code>Authentication</code> implementation for JSR-168 Portlet authentication. <p>The
|
||||
* <code>Authentication</code> implementation for JSR 168 Portlet authentication. <p>The
|
||||
* corresponding authentication provider is {@link PortletAuthenticationProvider}.</p>
|
||||
*
|
||||
* @author John A. Lewis
|
||||
|
||||
@@ -33,9 +33,10 @@ import org.acegisecurity.userdetails.User;
|
||||
import org.acegisecurity.userdetails.UserDetails;
|
||||
|
||||
/**
|
||||
* Populates the portlet authorities via role information from the portlet container.
|
||||
* <p>Populates the portlet authorities via role information from the portlet container.
|
||||
* Primarily it uses the <code>PortletRequest.isUserInRole(role)</code> method to
|
||||
* check if the user is in a list of configured roles.
|
||||
* check if the user is in a list of configured roles.</p>
|
||||
*
|
||||
* <p>This bean has the following configurable properties:</p>
|
||||
* <ul>
|
||||
* <li><code>rolesToCheck</code> : A list of strings containing names of roles to check.
|
||||
@@ -43,10 +44,16 @@ import org.acegisecurity.userdetails.UserDetails;
|
||||
* of the portlet descriptor in the portlet.xml file.</li>
|
||||
* <li><code>rolePrefix</code> : The prefix to be added onto each role name that as it is
|
||||
* added to the list of authorities. The default value is 'ROLE_'.</li>
|
||||
* <li><code>userRole</code> : The role that all authenticated users will automatically be
|
||||
* granted. The default value is 'ROLE_USER'.</li>
|
||||
* <li><code>userRole</code> : The authority that all authenticated users will automatically
|
||||
* be granted. The default value is 'ROLE_USER'. Set this to null to avoid having any
|
||||
* value automatically populated.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>This populator depends on finding the <code>PortletRequest<code> when calling the
|
||||
* {@link Authentication#getDetails()} method on the object passed to
|
||||
* {@link #getUserDetails(Authentication)}. If not, it will throw an
|
||||
* {@link AuthenticationServiceException}.
|
||||
*
|
||||
* @author John A. Lewis
|
||||
* @since 2.0
|
||||
* @version $Id$
|
||||
@@ -56,14 +63,14 @@ public class ContainerPortletAuthoritiesPopulator
|
||||
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final String defaultRolePrefix = "ROLE_";
|
||||
private static final String defaultUserRole = "ROLE_USER";
|
||||
public static final String DEFAULT_ROLE_PREFIX = "ROLE_";
|
||||
public static final String DEFAULT_USER_ROLE = "ROLE_USER";
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private List rolesToCheck;
|
||||
private String rolePrefix = defaultRolePrefix;
|
||||
private String userRole = defaultUserRole;
|
||||
private List rolesToCheck;
|
||||
private String rolePrefix = DEFAULT_ROLE_PREFIX;
|
||||
private String userRole = DEFAULT_USER_ROLE;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -77,7 +84,7 @@ public class ContainerPortletAuthoritiesPopulator
|
||||
// see if we can load authorities from the portlet request
|
||||
Object details = authentication.getDetails();
|
||||
if (!(details instanceof PortletRequest)) {
|
||||
throw new AuthenticationServiceException("expected getDetails() to return the PortletRequest object");
|
||||
throw new AuthenticationServiceException("expected Authentication.getDetails() to return a PortletRequest");
|
||||
}
|
||||
GrantedAuthority[] authorities = loadGrantedAuthorities((PortletRequest)details);
|
||||
|
||||
@@ -89,7 +96,8 @@ public class ContainerPortletAuthoritiesPopulator
|
||||
|
||||
// start the list and add the standard user role
|
||||
ArrayList authorities = new ArrayList();
|
||||
authorities.add(new GrantedAuthorityImpl(getUserRole()));
|
||||
if (this.userRole != null && this.userRole.length() > 0)
|
||||
authorities.add(new GrantedAuthorityImpl(getUserRole()));
|
||||
|
||||
// iterate through the configured list of roles to check (if there is one)
|
||||
if (this.rolesToCheck != null) {
|
||||
@@ -104,7 +112,7 @@ public class ContainerPortletAuthoritiesPopulator
|
||||
}
|
||||
}
|
||||
|
||||
// return the array of GrantedAuthority objects
|
||||
// return the array of GrantedAuthority objects
|
||||
return (GrantedAuthority[])authorities.toArray(new GrantedAuthority[authorities.size()]);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public class DaoPortletAuthoritiesPopulator
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private UserDetailsService userDetailsService;
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.acegisecurity.ui.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -25,6 +26,7 @@ import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
@@ -52,8 +54,8 @@ import org.springframework.web.portlet.ModelAndView;
|
||||
* {@link Authentication} object will be placed into the <code>SecurityContext</code>, which
|
||||
* is guaranteed to have already been created by an earlier interceptor. If authentication
|
||||
* fails, the <code>AuthenticationException</code> will be placed into the
|
||||
* <code>PortletSession</code> with the attribute defined by
|
||||
* {@link AbstractProcessingFilter#ACEGI_SECURITY_LAST_EXCEPTION_KEY}.</p>
|
||||
* <code>APPLICATION_SCOPE</code> of the <code>PortletSession</code> with the attribute defined
|
||||
* by {@link AbstractProcessingFilter#ACEGI_SECURITY_LAST_EXCEPTION_KEY}.</p>
|
||||
*
|
||||
* <p>Some portals do not properly provide the identity of the current user via the
|
||||
* <code>getRemoteUser()</code> or <code>getUserPrincipal()</code> methods of the
|
||||
@@ -167,7 +169,9 @@ public class PortletProcessingInterceptor implements
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Authentication failed - updating ContextHolder to contain null Authentication");
|
||||
ctx.setAuthentication(null);
|
||||
request.getPortletSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed);
|
||||
request.getPortletSession().setAttribute(
|
||||
AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY,
|
||||
failed, PortletSession.APPLICATION_SCOPE);
|
||||
onUnsuccessfulAuthentication(request, response, failed);
|
||||
}
|
||||
}
|
||||
@@ -177,7 +181,7 @@ public class PortletProcessingInterceptor implements
|
||||
|
||||
/**
|
||||
* This method attempts to extract a principal from the portlet request.
|
||||
* According to the JSR-168 spec, the <code>PortletRequest<code> should return the name
|
||||
* According to the JSR 168 spec, the <code>PortletRequest<code> should return the name
|
||||
* of the user in the <code>getRemoteUser()</code> method. It should also provide a
|
||||
* <code>java.security.Principal</code> object from the <code>getUserPrincipal()</code>
|
||||
* method. We will first try these to come up with a valid username.
|
||||
@@ -186,22 +190,25 @@ public class PortletProcessingInterceptor implements
|
||||
* property has been populated, then we will search through the <code>USER_INFO<code>
|
||||
* map from the request to see if we can find a valid username.
|
||||
* <p>This method can be overridden by subclasses to provide special handling
|
||||
* for portals with weak support for the JSR-168 spec.</p>
|
||||
* for portals with weak support for the JSR 168 spec.</p>
|
||||
* @param request the portlet request object
|
||||
* @return the determined principal object, or null if none found
|
||||
*/
|
||||
protected Object getPrincipalFromRequest(PortletRequest request) {
|
||||
|
||||
// first try getRemoteUser()
|
||||
Object principal = request.getRemoteUser();
|
||||
if (principal != null) {
|
||||
return principal;
|
||||
String remoteUser = request.getRemoteUser();
|
||||
if (remoteUser != null) {
|
||||
return remoteUser;
|
||||
}
|
||||
|
||||
// next try getUserPrincipal()
|
||||
principal = request.getUserPrincipal();
|
||||
if (principal != null) {
|
||||
return principal;
|
||||
Principal userPrincipal = request.getUserPrincipal();
|
||||
if (userPrincipal != null) {
|
||||
String userPrincipalName = userPrincipal.getName();
|
||||
if (userPrincipalName != null) {
|
||||
return userPrincipalName;
|
||||
}
|
||||
}
|
||||
|
||||
// last try entries in USER_INFO if any attributes were defined
|
||||
@@ -213,9 +220,9 @@ public class PortletProcessingInterceptor implements
|
||||
logger.warn("unable to retrieve USER_INFO map from portlet request", e);
|
||||
}
|
||||
if (userInfo != null) {
|
||||
Iterator i = this.userNameAttributes.iterator();
|
||||
while(i.hasNext()) {
|
||||
principal = (String)userInfo.get(i.next());
|
||||
Iterator i = this.userNameAttributes.iterator();
|
||||
while(i.hasNext()) {
|
||||
Object principal = (String)userInfo.get(i.next());
|
||||
if (principal != null) {
|
||||
return principal;
|
||||
}
|
||||
@@ -231,13 +238,13 @@ public class PortletProcessingInterceptor implements
|
||||
* This method attempts to extract a credentials from the portlet request.
|
||||
* We are trusting the portal framework to authenticate the user, so all
|
||||
* we are really doing is trying to put something intelligent in here to
|
||||
* indicate the user is authenticated. According to the JSR-168 spec,
|
||||
* indicate the user is authenticated. According to the JSR 168 spec,
|
||||
* PortletRequest.getAuthType() should return a non-null value if the
|
||||
* user is authenticated and should be null if not authenticated. So we
|
||||
* will use this as the credentials and the token will be trusted as
|
||||
* authenticated if the credentials are not null.
|
||||
* <p>This method can be overridden by subclasses to provide special handling
|
||||
* for portals with weak support for the JSR-168 spec. If that is done,
|
||||
* for portals with weak support for the JSR 168 spec. If that is done,
|
||||
* be sure the value is non-null for authenticated users and null for
|
||||
* non-authenticated users.</p>
|
||||
* @param request the portlet request object
|
||||
@@ -255,28 +262,28 @@ public class PortletProcessingInterceptor implements
|
||||
* @throws AuthenticationException to indicate that authentication attempt is not valid and should be terminated
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void onPreAuthentication(PortletRequest request, PortletResponse response)
|
||||
throws AuthenticationException, IOException {}
|
||||
protected void onPreAuthentication(PortletRequest request, PortletResponse response)
|
||||
throws AuthenticationException, IOException {}
|
||||
|
||||
/**
|
||||
* Callback for custom processing after a successful authentication attempt.
|
||||
* @param request the portlet request that was authenticated
|
||||
* @param response the portlet response that was authenticated
|
||||
* @param authResult the resulting Authentication object
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void onSuccessfulAuthentication(PortletRequest request, PortletResponse response, Authentication authResult)
|
||||
throws IOException {}
|
||||
/**
|
||||
* Callback for custom processing after a successful authentication attempt.
|
||||
* @param request the portlet request that was authenticated
|
||||
* @param response the portlet response that was authenticated
|
||||
* @param authResult the resulting Authentication object
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void onSuccessfulAuthentication(PortletRequest request, PortletResponse response, Authentication authResult)
|
||||
throws IOException {}
|
||||
|
||||
/**
|
||||
* Callback for custom processing after an unsuccessful authentication attempt.
|
||||
* @param request the portlet request that failed authentication
|
||||
* @param response the portlet response that failed authentication
|
||||
* @param failed the AuthenticationException that occurred
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void onUnsuccessfulAuthentication(PortletRequest request, PortletResponse response, AuthenticationException failed)
|
||||
throws IOException {}
|
||||
/**
|
||||
* Callback for custom processing after an unsuccessful authentication attempt.
|
||||
* @param request the portlet request that failed authentication
|
||||
* @param response the portlet response that failed authentication
|
||||
* @param failed the AuthenticationException that occurred
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void onUnsuccessfulAuthentication(PortletRequest request, PortletResponse response, AuthenticationException failed)
|
||||
throws IOException {}
|
||||
|
||||
|
||||
public AuthenticationManager getAuthenticationManager() {
|
||||
|
||||
Reference in New Issue
Block a user