mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-07 11:12:14 +00:00
SEC-1246: Introduce EL-based authorization tag. Added optional access expression to authorize tag.
This commit is contained in:
parent
283aa1b34b
commit
b531a81176
@ -5,7 +5,7 @@
|
|||||||
<h1>VERY Secure Page</h1>
|
<h1>VERY Secure Page</h1>
|
||||||
This is a protected page. You can only see me if you are a supervisor.
|
This is a protected page. You can only see me if you are a supervisor.
|
||||||
|
|
||||||
<authz:authorize ifAllGranted="ROLE_SUPERVISOR">
|
<authz:authorize access="hasRole('ROLE_SUPERVISOR')">
|
||||||
You have "ROLE_SUPERVISOR" (this text is surrounded by <authz:authorize> tags).
|
You have "ROLE_SUPERVISOR" (this text is surrounded by <authz:authorize> tags).
|
||||||
</authz:authorize>
|
</authz:authorize>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ This is a protected page. You can get to me if you've been remembered,
|
|||||||
or if you've authenticated this session.
|
or if you've authenticated this session.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<sec:authorize ifAllGranted="ROLE_SUPERVISOR">
|
<sec:authorize access="hasRole('ROLE_SUPERVISOR')">
|
||||||
You are a supervisor! You can therefore see the <a href="extreme/index.jsp">extremely secure page</a>.<br/><br/>
|
You are a supervisor! You can therefore see the <a href="extreme/index.jsp">extremely secure page</a>.<br/><br/>
|
||||||
</sec:authorize>
|
</sec:authorize>
|
||||||
|
|
||||||
|
@ -1,197 +1,87 @@
|
|||||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.security.taglibs.authz;
|
package org.springframework.security.taglibs.authz;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Map;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.jsp.JspException;
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
|
||||||
import javax.servlet.jsp.tagext.TagSupport;
|
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.expression.Expression;
|
||||||
|
import org.springframework.expression.ParseException;
|
||||||
|
import org.springframework.security.access.expression.ExpressionUtils;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.authority.AuthorityUtils;
|
|
||||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.web.util.ExpressionEvaluationUtils;
|
import org.springframework.security.web.FilterInvocation;
|
||||||
|
import org.springframework.security.web.access.expression.WebSecurityExpressionHandler;
|
||||||
|
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows it's body through if some authorizations
|
* Expression-based access control tag.
|
||||||
* are granted to the request's principal.
|
|
||||||
*
|
*
|
||||||
* @author Francois Beausoleil
|
* @author Luke Taylor
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class AuthorizeTag extends TagSupport {
|
public class AuthorizeTag extends LegacyAuthorizeTag {
|
||||||
//~ Instance fields ================================================================================================
|
private String access;
|
||||||
|
|
||||||
private String ifAllGranted = "";
|
|
||||||
private String ifAnyGranted = "";
|
|
||||||
private String ifNotGranted = "";
|
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
|
||||||
|
|
||||||
private Set<String> authoritiesToRoles(Collection<GrantedAuthority> c) {
|
|
||||||
Set<String> target = new HashSet<String>();
|
|
||||||
|
|
||||||
for (GrantedAuthority authority : c) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// If access expression evaluates to "true" return
|
||||||
public int doStartTag() throws JspException {
|
public int doStartTag() throws JspException {
|
||||||
if (((null == ifAllGranted) || "".equals(ifAllGranted)) && ((null == ifAnyGranted) || "".equals(ifAnyGranted))
|
if (access == null || access.length() == 0) {
|
||||||
&& ((null == ifNotGranted) || "".equals(ifNotGranted))) {
|
return super.doStartTag();
|
||||||
return Tag.SKIP_BODY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Collection<GrantedAuthority> granted = getPrincipalAuthorities();
|
|
||||||
|
|
||||||
final String evaledIfNotGranted = ExpressionEvaluationUtils.evaluateString("ifNotGranted", ifNotGranted,
|
|
||||||
pageContext);
|
|
||||||
|
|
||||||
if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) {
|
|
||||||
Set<GrantedAuthority> grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfNotGranted));
|
|
||||||
|
|
||||||
if (!grantedCopy.isEmpty()) {
|
|
||||||
return Tag.SKIP_BODY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final String evaledIfAllGranted = ExpressionEvaluationUtils.evaluateString("ifAllGranted", ifAllGranted,
|
|
||||||
pageContext);
|
|
||||||
|
|
||||||
if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) {
|
|
||||||
if (!granted.containsAll(parseAuthoritiesString(evaledIfAllGranted))) {
|
|
||||||
return Tag.SKIP_BODY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final String evaledIfAnyGranted = ExpressionEvaluationUtils.evaluateString("ifAnyGranted", ifAnyGranted,
|
|
||||||
pageContext);
|
|
||||||
|
|
||||||
if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) {
|
|
||||||
Set<GrantedAuthority> grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfAnyGranted));
|
|
||||||
|
|
||||||
if (grantedCopy.isEmpty()) {
|
|
||||||
return Tag.SKIP_BODY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Tag.EVAL_BODY_INCLUDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIfAllGranted() {
|
|
||||||
return ifAllGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIfAnyGranted() {
|
|
||||||
return ifAnyGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIfNotGranted() {
|
|
||||||
return ifNotGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Collection<GrantedAuthority> getPrincipalAuthorities() {
|
|
||||||
Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
|
Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
|
||||||
if (null == currentUser) {
|
if (currentUser == null) {
|
||||||
return Collections.emptyList();
|
return SKIP_BODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((null == currentUser.getAuthorities())) {
|
// Get web expression
|
||||||
return Collections.emptyList();
|
WebSecurityExpressionHandler handler = getExpressionHandler();
|
||||||
|
|
||||||
|
Expression accessExpression;
|
||||||
|
try {
|
||||||
|
accessExpression = handler.getExpressionParser().parseExpression(access);
|
||||||
|
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new JspException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentUser.getAuthorities();
|
FilterInvocation f = new FilterInvocation(pageContext.getRequest(), pageContext.getResponse(), DUMMY_CHAIN);
|
||||||
|
|
||||||
|
if (ExpressionUtils.evaluateAsBoolean(accessExpression, handler.createEvaluationContext(currentUser, f))) {
|
||||||
|
return EVAL_BODY_INCLUDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<GrantedAuthority> parseAuthoritiesString(String authorizationsString) {
|
return SKIP_BODY;
|
||||||
final Set<GrantedAuthority> requiredAuthorities = new HashSet<GrantedAuthority>();
|
|
||||||
requiredAuthorities.addAll(AuthorityUtils.commaSeparatedStringToAuthorityList(authorizationsString));
|
|
||||||
|
|
||||||
return requiredAuthorities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setAccess(String access) {
|
||||||
* Find the common authorities between the current authentication's {@link GrantedAuthority} and the ones
|
this.access = access;
|
||||||
* 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 GrantedAuthority#getAuthority()}.
|
|
||||||
* </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
|
|
||||||
* 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>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private Set<GrantedAuthority> retainAll(final Collection<GrantedAuthority> granted, final Set<GrantedAuthority> required) {
|
|
||||||
Set<String> grantedRoles = authoritiesToRoles(granted);
|
|
||||||
Set<String> requiredRoles = authoritiesToRoles(required);
|
|
||||||
grantedRoles.retainAll(requiredRoles);
|
|
||||||
|
|
||||||
return rolesToAuthorities(grantedRoles, granted);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<GrantedAuthority> rolesToAuthorities(Set<String> grantedRoles, Collection<GrantedAuthority> granted) {
|
WebSecurityExpressionHandler getExpressionHandler() throws JspException {
|
||||||
Set<GrantedAuthority> target = new HashSet<GrantedAuthority>();
|
ServletContext servletContext = pageContext.getServletContext();
|
||||||
|
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
|
||||||
|
Map<String, WebSecurityExpressionHandler> expressionHdlrs = ctx.getBeansOfType(WebSecurityExpressionHandler.class);
|
||||||
|
|
||||||
for (String role : grantedRoles) {
|
if (expressionHdlrs.size() == 0) {
|
||||||
for (GrantedAuthority authority : granted) {
|
throw new JspException("No visible WebSecurityExpressionHandler instance could be found in the application " +
|
||||||
if (authority.getAuthority().equals(role)) {
|
"context. There must be at least one in order to use expressions with taglib support.");
|
||||||
target.add(authority);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return target;
|
return (WebSecurityExpressionHandler) expressionHdlrs.values().toArray()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIfAllGranted(String ifAllGranted) throws JspException {
|
private static final FilterChain DUMMY_CHAIN = new FilterChain() {
|
||||||
this.ifAllGranted = ifAllGranted;
|
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
|
||||||
}
|
throw new UnsupportedOperationException();
|
||||||
|
|
||||||
public void setIfAnyGranted(String ifAnyGranted) throws JspException {
|
|
||||||
this.ifAnyGranted = ifAnyGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIfNotGranted(String ifNotGranted) throws JspException {
|
|
||||||
this.ifNotGranted = ifNotGranted;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,197 @@
|
|||||||
|
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.security.taglibs.authz;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException;
|
||||||
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
import javax.servlet.jsp.tagext.TagSupport;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
|
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.web.util.ExpressionEvaluationUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows it's body through if some authorizations
|
||||||
|
* are granted to the request's principal.
|
||||||
|
*
|
||||||
|
* @author Francois Beausoleil
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class LegacyAuthorizeTag extends TagSupport {
|
||||||
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
|
private String ifAllGranted = "";
|
||||||
|
private String ifAnyGranted = "";
|
||||||
|
private String ifNotGranted = "";
|
||||||
|
|
||||||
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
|
private Set<String> authoritiesToRoles(Collection<GrantedAuthority> c) {
|
||||||
|
Set<String> target = new HashSet<String>();
|
||||||
|
|
||||||
|
for (GrantedAuthority authority : c) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int doStartTag() throws JspException {
|
||||||
|
if (((null == ifAllGranted) || "".equals(ifAllGranted)) && ((null == ifAnyGranted) || "".equals(ifAnyGranted))
|
||||||
|
&& ((null == ifNotGranted) || "".equals(ifNotGranted))) {
|
||||||
|
return Tag.SKIP_BODY;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Collection<GrantedAuthority> granted = getPrincipalAuthorities();
|
||||||
|
|
||||||
|
final String evaledIfNotGranted = ExpressionEvaluationUtils.evaluateString("ifNotGranted", ifNotGranted,
|
||||||
|
pageContext);
|
||||||
|
|
||||||
|
if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) {
|
||||||
|
Set<GrantedAuthority> grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfNotGranted));
|
||||||
|
|
||||||
|
if (!grantedCopy.isEmpty()) {
|
||||||
|
return Tag.SKIP_BODY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final String evaledIfAllGranted = ExpressionEvaluationUtils.evaluateString("ifAllGranted", ifAllGranted,
|
||||||
|
pageContext);
|
||||||
|
|
||||||
|
if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) {
|
||||||
|
if (!granted.containsAll(parseAuthoritiesString(evaledIfAllGranted))) {
|
||||||
|
return Tag.SKIP_BODY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final String evaledIfAnyGranted = ExpressionEvaluationUtils.evaluateString("ifAnyGranted", ifAnyGranted,
|
||||||
|
pageContext);
|
||||||
|
|
||||||
|
if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) {
|
||||||
|
Set<GrantedAuthority> grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfAnyGranted));
|
||||||
|
|
||||||
|
if (grantedCopy.isEmpty()) {
|
||||||
|
return Tag.SKIP_BODY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Tag.EVAL_BODY_INCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIfAllGranted() {
|
||||||
|
return ifAllGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIfAnyGranted() {
|
||||||
|
return ifAnyGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIfNotGranted() {
|
||||||
|
return ifNotGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<GrantedAuthority> getPrincipalAuthorities() {
|
||||||
|
Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
|
||||||
|
if (null == currentUser) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((null == currentUser.getAuthorities())) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentUser.getAuthorities();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<GrantedAuthority> parseAuthoritiesString(String authorizationsString) {
|
||||||
|
final Set<GrantedAuthority> requiredAuthorities = new HashSet<GrantedAuthority>();
|
||||||
|
requiredAuthorities.addAll(AuthorityUtils.commaSeparatedStringToAuthorityList(authorizationsString));
|
||||||
|
|
||||||
|
return 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 GrantedAuthority#getAuthority()}.
|
||||||
|
* </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
|
||||||
|
* 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>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private Set<GrantedAuthority> retainAll(final Collection<GrantedAuthority> granted, final Set<GrantedAuthority> required) {
|
||||||
|
Set<String> grantedRoles = authoritiesToRoles(granted);
|
||||||
|
Set<String> requiredRoles = authoritiesToRoles(required);
|
||||||
|
grantedRoles.retainAll(requiredRoles);
|
||||||
|
|
||||||
|
return rolesToAuthorities(grantedRoles, granted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<GrantedAuthority> rolesToAuthorities(Set<String> grantedRoles, Collection<GrantedAuthority> granted) {
|
||||||
|
Set<GrantedAuthority> target = new HashSet<GrantedAuthority>();
|
||||||
|
|
||||||
|
for (String role : grantedRoles) {
|
||||||
|
for (GrantedAuthority authority : granted) {
|
||||||
|
if (authority.getAuthority().equals(role)) {
|
||||||
|
target.add(authority);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIfAllGranted(String ifAllGranted) throws JspException {
|
||||||
|
this.ifAllGranted = ifAllGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIfAnyGranted(String ifAnyGranted) throws JspException {
|
||||||
|
this.ifAnyGranted = ifAnyGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIfNotGranted(String ifNotGranted) throws JspException {
|
||||||
|
this.ifNotGranted = ifNotGranted;
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ package org.springframework.security.taglibs.velocity;
|
|||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.taglibs.authz.AuthenticationTag;
|
import org.springframework.security.taglibs.authz.AuthenticationTag;
|
||||||
import org.springframework.security.taglibs.authz.AuthorizeTag;
|
import org.springframework.security.taglibs.authz.LegacyAuthorizeTag;
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
@ -27,7 +27,7 @@ import org.springframework.context.ApplicationContext;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper the implementation of Spring Security JSP tag includes:
|
* Wrapper the implementation of Spring Security JSP tag includes:
|
||||||
* {@link AuthenticationTag}, {@link AclTag}, {@link AuthorizeTag}
|
* {@link AuthenticationTag}, {@link AclTag}, {@link LegacyAuthorizeTag}
|
||||||
*
|
*
|
||||||
* @author Wang Qi
|
* @author Wang Qi
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
|
@ -20,7 +20,7 @@ import javax.servlet.jsp.tagext.Tag;
|
|||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.security.taglibs.authz.AuthenticationTag;
|
import org.springframework.security.taglibs.authz.AuthenticationTag;
|
||||||
import org.springframework.security.taglibs.authz.AuthorizeTag;
|
import org.springframework.security.taglibs.authz.LegacyAuthorizeTag;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +72,7 @@ public class AuthzImpl implements Authz {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* implementation of AuthorizeTag
|
* implementation of LegacyAuthorizeTag
|
||||||
*
|
*
|
||||||
* @param roles DOCUMENT ME!
|
* @param roles DOCUMENT ME!
|
||||||
* @param grantType DOCUMENT ME!
|
* @param grantType DOCUMENT ME!
|
||||||
@ -82,7 +82,7 @@ public class AuthzImpl implements Authz {
|
|||||||
* @throws IllegalArgumentException DOCUMENT ME!
|
* @throws IllegalArgumentException DOCUMENT ME!
|
||||||
*/
|
*/
|
||||||
private boolean ifGranted(String roles, int grantType) {
|
private boolean ifGranted(String roles, int grantType) {
|
||||||
AuthorizeTag authorizeTag = new AuthorizeTag();
|
LegacyAuthorizeTag authorizeTag = new LegacyAuthorizeTag();
|
||||||
|
|
||||||
int result = -1;
|
int result = -1;
|
||||||
|
|
||||||
|
@ -16,17 +16,27 @@
|
|||||||
<name>authorize</name>
|
<name>authorize</name>
|
||||||
<tag-class>org.springframework.security.taglibs.authz.AuthorizeTag</tag-class>
|
<tag-class>org.springframework.security.taglibs.authz.AuthorizeTag</tag-class>
|
||||||
<description>
|
<description>
|
||||||
A simple tag to output or not the body of the tag if the principal
|
A tag which outputs the body of the tag if the configured access expression
|
||||||
has or doesn't have certain authorities.
|
evaluates to true for the currently authenticated principal.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
|
<attribute>
|
||||||
|
<name>access</name>
|
||||||
|
<required>false</required>
|
||||||
|
<rtexprvalue>false</rtexprvalue>
|
||||||
|
<description>
|
||||||
|
A Spring-EL expression which is supported by the WebSecurityExpressionHandler
|
||||||
|
in the application context. The latter will be used to evaluate the expression.
|
||||||
|
</description>
|
||||||
|
</attribute>
|
||||||
|
|
||||||
<attribute>
|
<attribute>
|
||||||
<name>ifNotGranted</name>
|
<name>ifNotGranted</name>
|
||||||
<required>false</required>
|
<required>false</required>
|
||||||
<rtexprvalue>true</rtexprvalue>
|
<rtexprvalue>true</rtexprvalue>
|
||||||
<description>
|
<description>
|
||||||
A comma separated list of roles which the user must not have
|
A comma separated list of roles which the user must not have
|
||||||
for the body to be output.
|
for the body to be output. Deprecated in favour of the access expression.
|
||||||
</description>
|
</description>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
|
||||||
@ -36,7 +46,7 @@
|
|||||||
<rtexprvalue>true</rtexprvalue>
|
<rtexprvalue>true</rtexprvalue>
|
||||||
<description>
|
<description>
|
||||||
A comma separated list of roles which the user must all
|
A comma separated list of roles which the user must all
|
||||||
possess for the body to be output.
|
possess for the body to be output. Deprecated in favour of the access expression.
|
||||||
</description>
|
</description>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
|
||||||
@ -46,7 +56,7 @@
|
|||||||
<rtexprvalue>true</rtexprvalue>
|
<rtexprvalue>true</rtexprvalue>
|
||||||
<description>
|
<description>
|
||||||
A comma separated list of roles, one of which the user must
|
A comma separated list of roles, one of which the user must
|
||||||
possess for the body to be output.
|
possess for the body to be output. Deprecated in favour of the access expression.
|
||||||
</description>
|
</description>
|
||||||
</attribute>
|
</attribute>
|
||||||
</tag>
|
</tag>
|
||||||
|
@ -37,7 +37,7 @@ import javax.servlet.jsp.tagext.Tag;
|
|||||||
public class AuthorizeTagAttributeTests extends TestCase {
|
public class AuthorizeTagAttributeTests extends TestCase {
|
||||||
//~ Instance fields ================================================================================================
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
private final AuthorizeTag authorizeTag = new AuthorizeTag();
|
private final LegacyAuthorizeTag authorizeTag = new LegacyAuthorizeTag();
|
||||||
private TestingAuthenticationToken currentUser;
|
private TestingAuthenticationToken currentUser;
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
@ -35,7 +35,7 @@ import javax.servlet.jsp.tagext.Tag;
|
|||||||
public class AuthorizeTagCustomGrantedAuthorityTests extends TestCase {
|
public class AuthorizeTagCustomGrantedAuthorityTests extends TestCase {
|
||||||
//~ Instance fields ================================================================================================
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
private final AuthorizeTag authorizeTag = new AuthorizeTag();
|
private final LegacyAuthorizeTag authorizeTag = new LegacyAuthorizeTag();
|
||||||
private TestingAuthenticationToken currentUser;
|
private TestingAuthenticationToken currentUser;
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
@ -36,7 +36,7 @@ public class AuthorizeTagExpressionLanguageTests extends TestCase {
|
|||||||
Mockery jmock = new Mockery();
|
Mockery jmock = new Mockery();
|
||||||
//~ Instance fields ================================================================================================
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
private final AuthorizeTag authorizeTag = new AuthorizeTag();
|
private final LegacyAuthorizeTag authorizeTag = new LegacyAuthorizeTag();
|
||||||
private MockPageContext pageContext;
|
private MockPageContext pageContext;
|
||||||
private TestingAuthenticationToken currentUser;
|
private TestingAuthenticationToken currentUser;
|
||||||
|
|
||||||
|
@ -15,97 +15,131 @@
|
|||||||
|
|
||||||
package org.springframework.security.taglibs.authz;
|
package org.springframework.security.taglibs.authz;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
|
|
||||||
|
|
||||||
import javax.servlet.jsp.JspException;
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
import org.springframework.mock.web.MockPageContext;
|
||||||
|
import org.springframework.mock.web.MockServletContext;
|
||||||
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOCUMENT ME!
|
|
||||||
*
|
|
||||||
* @author Francois Beausoleil
|
* @author Francois Beausoleil
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class AuthorizeTagTests extends TestCase {
|
public class AuthorizeTagTests {
|
||||||
//~ Instance fields ================================================================================================
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
private final AuthorizeTag authorizeTag = new AuthorizeTag();
|
private AuthorizeTag authorizeTag;
|
||||||
private TestingAuthenticationToken currentUser;
|
private final TestingAuthenticationToken currentUser = new TestingAuthenticationToken("abc", "123", "ROLE SUPERVISOR", "ROLE_TELLER");
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
protected void setUp() throws Exception {
|
@Before
|
||||||
super.setUp();
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
currentUser = new TestingAuthenticationToken("abc", "123",
|
|
||||||
new GrantedAuthority[] {
|
|
||||||
new GrantedAuthorityImpl("ROLE SUPERVISOR"), new GrantedAuthorityImpl("ROLE_TELLER"),
|
|
||||||
});
|
|
||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(currentUser);
|
SecurityContextHolder.getContext().setAuthentication(currentUser);
|
||||||
|
StaticWebApplicationContext ctx = new StaticWebApplicationContext();
|
||||||
|
ctx.registerSingleton("expressionHandler", DefaultWebSecurityExpressionHandler.class);
|
||||||
|
MockServletContext servletCtx = new MockServletContext();
|
||||||
|
servletCtx.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ctx);
|
||||||
|
authorizeTag = new AuthorizeTag();
|
||||||
|
authorizeTag.setPageContext(new MockPageContext(servletCtx, new MockHttpServletRequest(), new MockHttpServletResponse()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void tearDown() throws Exception {
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAlwaysReturnsUnauthorizedIfNoUserFound() throws JspException {
|
// access attribute tests
|
||||||
SecurityContextHolder.getContext().setAuthentication(null);
|
|
||||||
|
|
||||||
authorizeTag.setIfAllGranted("ROLE_TELLER");
|
@Test
|
||||||
assertEquals("prevents request - no principal in Context", Tag.SKIP_BODY, authorizeTag.doStartTag());
|
public void skipsBodyIfNoAuthenticationPresent() throws Exception {
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
|
authorizeTag.setAccess("permitAll");
|
||||||
|
assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void skipsBodyIfAccessExpressionDeniesAccess() throws Exception {
|
||||||
|
authorizeTag.setAccess("denyAll");
|
||||||
|
assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showsBodyIfAccessExpressionAllowsAccess() throws Exception {
|
||||||
|
authorizeTag.setAccess("permitAll");
|
||||||
|
assertEquals(Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
|
||||||
|
}
|
||||||
|
// Legacy attribute tests
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAlwaysReturnsUnauthorizedIfNoUserFound() throws JspException {
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
|
authorizeTag.setIfAllGranted("ROLE_TELLER");
|
||||||
|
assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testDefaultsToNotOutputtingBodyWhenNoRequiredAuthorities() throws JspException {
|
public void testDefaultsToNotOutputtingBodyWhenNoRequiredAuthorities() throws JspException {
|
||||||
assertEquals("", authorizeTag.getIfAllGranted());
|
assertEquals("", authorizeTag.getIfAllGranted());
|
||||||
assertEquals("", authorizeTag.getIfAnyGranted());
|
assertEquals("", authorizeTag.getIfAnyGranted());
|
||||||
assertEquals("", authorizeTag.getIfNotGranted());
|
assertEquals("", authorizeTag.getIfNotGranted());
|
||||||
|
|
||||||
assertEquals("prevents body output - no authorities granted", Tag.SKIP_BODY, authorizeTag.doStartTag());
|
assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testOutputsBodyIfOneRolePresent() throws JspException {
|
public void testOutputsBodyIfOneRolePresent() throws JspException {
|
||||||
authorizeTag.setIfAnyGranted("ROLE_TELLER");
|
authorizeTag.setIfAnyGranted("ROLE_TELLER");
|
||||||
assertEquals("authorized - ROLE_TELLER in both sets", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
|
assertEquals(Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testOutputsBodyWhenAllGranted() throws JspException {
|
public void testOutputsBodyWhenAllGranted() throws JspException {
|
||||||
authorizeTag.setIfAllGranted("ROLE SUPERVISOR, \nROLE_TELLER");
|
authorizeTag.setIfAllGranted("ROLE SUPERVISOR, \nROLE_TELLER");
|
||||||
assertEquals("allows request - all required roles granted on principal", Tag.EVAL_BODY_INCLUDE,
|
assertEquals(Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
|
||||||
authorizeTag.doStartTag());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testOutputsBodyWhenNotGrantedSatisfied() throws JspException {
|
public void testOutputsBodyWhenNotGrantedSatisfied() throws JspException {
|
||||||
authorizeTag.setIfNotGranted("ROLE_BANKER");
|
authorizeTag.setIfNotGranted("ROLE_BANKER");
|
||||||
assertEquals("allows request - principal doesn't have ROLE_BANKER", Tag.EVAL_BODY_INCLUDE,
|
assertEquals(Tag.EVAL_BODY_INCLUDE,
|
||||||
authorizeTag.doStartTag());
|
authorizeTag.doStartTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testPreventsBodyOutputIfNoSecurityContext() throws JspException {
|
public void testPreventsBodyOutputIfNoSecurityContext() throws JspException {
|
||||||
SecurityContextHolder.getContext().setAuthentication(null);
|
SecurityContextHolder.getContext().setAuthentication(null);
|
||||||
authorizeTag.setIfAnyGranted("ROLE_BANKER");
|
authorizeTag.setIfAnyGranted("ROLE_BANKER");
|
||||||
|
|
||||||
assertEquals("prevents output - no context defined", Tag.SKIP_BODY, authorizeTag.doStartTag());
|
assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSkipsBodyIfNoAnyRolePresent() throws JspException {
|
public void testSkipsBodyIfNoAnyRolePresent() throws JspException {
|
||||||
authorizeTag.setIfAnyGranted("ROLE_BANKER");
|
authorizeTag.setIfAnyGranted("ROLE_BANKER");
|
||||||
assertEquals("unauthorized - ROLE_BANKER not in granted authorities", Tag.SKIP_BODY, authorizeTag.doStartTag());
|
assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSkipsBodyWhenMissingAnAllGranted() throws JspException {
|
public void testSkipsBodyWhenMissingAnAllGranted() throws JspException {
|
||||||
authorizeTag.setIfAllGranted("ROLE SUPERVISOR, ROLE_TELLER,\n\rROLE_BANKER");
|
authorizeTag.setIfAllGranted("ROLE SUPERVISOR, ROLE_TELLER,\n\rROLE_BANKER");
|
||||||
assertEquals("prevents request - missing ROLE_BANKER on principal", Tag.SKIP_BODY, authorizeTag.doStartTag());
|
assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSkipsBodyWhenNotGrantedUnsatisfied() throws JspException {
|
public void testSkipsBodyWhenNotGrantedUnsatisfied() throws JspException {
|
||||||
authorizeTag.setIfNotGranted("ROLE_TELLER");
|
authorizeTag.setIfNotGranted("ROLE_TELLER");
|
||||||
assertEquals("prevents request - principal has ROLE_TELLER", Tag.SKIP_BODY, authorizeTag.doStartTag());
|
assertEquals("prevents request - principal has ROLE_TELLER", Tag.SKIP_BODY, authorizeTag.doStartTag());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user