|
@@ -16,10 +16,13 @@
|
|
package net.sf.acegisecurity.taglibs.authz;
|
|
package net.sf.acegisecurity.taglibs.authz;
|
|
|
|
|
|
import net.sf.acegisecurity.Authentication;
|
|
import net.sf.acegisecurity.Authentication;
|
|
|
|
+import net.sf.acegisecurity.GrantedAuthority;
|
|
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
|
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
|
import net.sf.acegisecurity.context.ContextHolder;
|
|
import net.sf.acegisecurity.context.ContextHolder;
|
|
import net.sf.acegisecurity.context.security.SecureContext;
|
|
import net.sf.acegisecurity.context.security.SecureContext;
|
|
|
|
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
+
|
|
import org.springframework.web.util.ExpressionEvaluationUtils;
|
|
import org.springframework.web.util.ExpressionEvaluationUtils;
|
|
|
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
@@ -132,24 +135,104 @@ public class AuthorizeTag extends TagSupport {
|
|
return granted;
|
|
return granted;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private Set authoritiesToRoles(Collection c) {
|
|
|
|
+ Set target = new HashSet();
|
|
|
|
+
|
|
|
|
+ for (Iterator iterator = c.iterator(); iterator.hasNext();) {
|
|
|
|
+ GrantedAuthority authority = (GrantedAuthority) iterator.next();
|
|
|
|
+
|
|
|
|
+ if (null == authority.getAuthority()) {
|
|
|
|
+ throw new IllegalArgumentException(
|
|
|
|
+ "Cannot process GrantedAuthority objects which return null from getAuthority() - attempting to process "
|
|
|
|
+ + authority.toString());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ target.add(authority.getAuthority());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return target;
|
|
|
|
+ }
|
|
|
|
+
|
|
private Set parseAuthoritiesString(String authorizationsString) {
|
|
private Set parseAuthoritiesString(String authorizationsString) {
|
|
final Set requiredAuthorities = new HashSet();
|
|
final Set requiredAuthorities = new HashSet();
|
|
- final StringTokenizer tokenizer;
|
|
|
|
- tokenizer = new StringTokenizer(authorizationsString, ",", false);
|
|
|
|
|
|
+ final String[] authorities = StringUtils
|
|
|
|
+ .commaDelimitedListToStringArray(authorizationsString);
|
|
|
|
|
|
- while (tokenizer.hasMoreTokens()) {
|
|
|
|
- String role = tokenizer.nextToken();
|
|
|
|
- requiredAuthorities.add(new GrantedAuthorityImpl(role.trim()));
|
|
|
|
|
|
+ for (int i = 0; i < authorities.length; i++) {
|
|
|
|
+ String authority = authorities[i];
|
|
|
|
+ String role = authority.replaceAll("\\s+", "");
|
|
|
|
+ requiredAuthorities.add(new GrantedAuthorityImpl(role));
|
|
}
|
|
}
|
|
|
|
|
|
return requiredAuthorities;
|
|
return requiredAuthorities;
|
|
}
|
|
}
|
|
|
|
|
|
- private Set retainAll(final Collection granted,
|
|
|
|
- final Set requiredAuthorities) {
|
|
|
|
- Set grantedCopy = new HashSet(granted);
|
|
|
|
- grantedCopy.retainAll(requiredAuthorities);
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Find the common authorities between the current authentication's {@link
|
|
|
|
+ * GrantedAuthority} and the ones that have been specified in the tag's
|
|
|
|
+ * ifAny, ifNot or ifAllGranted attributes.
|
|
|
|
+ *
|
|
|
|
+ * <p>
|
|
|
|
+ * We need to manually iterate over both collections, because the granted
|
|
|
|
+ * authorities might not implement {@link Object#equals(Object)} and
|
|
|
|
+ * {@link Object#hashCode()} in the same way as {@link
|
|
|
|
+ * GrantedAuthorityImpl}, thereby invalidating {@link
|
|
|
|
+ * Collection#retainAll(java.util.Collection)} results.
|
|
|
|
+ * </p>
|
|
|
|
+ *
|
|
|
|
+ * <p>
|
|
|
|
+ * <strong>CAVEAT</strong>: This method <strong>will not</strong> work if
|
|
|
|
+ * the granted authorities returns a <code>null</code> string as the
|
|
|
|
+ * return value of {@link
|
|
|
|
+ * net.sf.acegisecurity.GrantedAuthority#getAuthority()}.
|
|
|
|
+ * </p>
|
|
|
|
+ *
|
|
|
|
+ * <p>
|
|
|
|
+ * Reported by rawdave, on Fri Feb 04, 2005 2:11 pm in the Acegi Security
|
|
|
|
+ * System for Spring forums.
|
|
|
|
+ * </p>
|
|
|
|
+ *
|
|
|
|
+ * @param granted The authorities granted by the authentication. May be any
|
|
|
|
+ * implementation of {@link GrantedAuthority} that does
|
|
|
|
+ * <strong>not</strong> return <code>null</code> from {@link
|
|
|
|
+ * net.sf.acegisecurity.GrantedAuthority#getAuthority()}.
|
|
|
|
+ * @param required A {@link Set} of {@link GrantedAuthorityImpl}s that have
|
|
|
|
+ * been built using ifAny, ifAll or ifNotGranted.
|
|
|
|
+ *
|
|
|
|
+ * @return A set containing only the common authorities between
|
|
|
|
+ * <var>granted</var> and <var>required</var>.
|
|
|
|
+ *
|
|
|
|
+ * @see <a
|
|
|
|
+ * href="http://forum.springframework.org/viewtopic.php?t=3367">authz:authorize
|
|
|
|
+ * ifNotGranted not behaving as expected</a>
|
|
|
|
+ */
|
|
|
|
+ private Set retainAll(final Collection granted, final Set required) {
|
|
|
|
+ Set grantedRoles = authoritiesToRoles(granted);
|
|
|
|
+ Set requiredRoles = authoritiesToRoles(required);
|
|
|
|
+ grantedRoles.retainAll(requiredRoles);
|
|
|
|
+
|
|
|
|
+ return rolesToAuthorities(grantedRoles, granted);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Set rolesToAuthorities(Set grantedRoles, Collection granted) {
|
|
|
|
+ Set target = new HashSet();
|
|
|
|
+
|
|
|
|
+ for (Iterator iterator = grantedRoles.iterator(); iterator.hasNext();) {
|
|
|
|
+ String role = (String) iterator.next();
|
|
|
|
+
|
|
|
|
+ for (Iterator grantedIterator = granted.iterator();
|
|
|
|
+ grantedIterator.hasNext();) {
|
|
|
|
+ GrantedAuthority authority = (GrantedAuthority) grantedIterator
|
|
|
|
+ .next();
|
|
|
|
+
|
|
|
|
+ if (authority.getAuthority().equals(role)) {
|
|
|
|
+ target.add(authority);
|
|
|
|
+
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- return grantedCopy;
|
|
|
|
|
|
+ return target;
|
|
}
|
|
}
|
|
}
|
|
}
|