diff --git a/spring-faces/.classpath b/spring-faces/.classpath
index 8c8ac035..d73b9c86 100644
--- a/spring-faces/.classpath
+++ b/spring-faces/.classpath
@@ -29,6 +29,8 @@
+
+
diff --git a/spring-faces/ivy.xml b/spring-faces/ivy.xml
index 26be6c28..326223d4 100644
--- a/spring-faces/ivy.xml
+++ b/spring-faces/ivy.xml
@@ -37,6 +37,8 @@
+
+
diff --git a/spring-faces/src/main/java/org/springframework/faces/security/AbstractAuthorizeTag.java b/spring-faces/src/main/java/org/springframework/faces/security/AbstractAuthorizeTag.java
new file mode 100644
index 00000000..38ef73bc
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/security/AbstractAuthorizeTag.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2004-2010 the original author or authors.
+ *
+ * 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.faces.security;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+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.http.HttpServletRequest;
+
+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.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.FilterInvocation;
+import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
+import org.springframework.security.web.access.expression.WebSecurityExpressionHandler;
+import org.springframework.util.StringUtils;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+/**
+ *
+ * A base class for an <authorize> tag used to make Spring Security based authorization decisions.
+ *
+ *
+ *
+ * This class is independent of tag rendering technology (JSP, Facelets). It treats tag attributes as simple strings
+ * (with the notable exception of the "access" attribute, which is always expected to contain a Spring EL expression).
+ * Therefore subclasses are expected to extract tag attribute values from the specific rendering technology, evaluate
+ * them as expressions if necessary, and use the result to set the String-based attributes of this class.
+ *
+ *
+ * @author Francois Beausoleil
+ * @author Luke Taylor
+ * @author Rossen Stoyanchev
+ *
+ * @since 2.2.0
+ */
+public abstract class AbstractAuthorizeTag {
+
+ private String access;
+ private String url;
+ private String method;
+ private String ifAllGranted;
+ private String ifAnyGranted;
+ private String ifNotGranted;
+
+ /**
+ * This method allows subclasses to provide a way to access the ServletRequest according to the rendering
+ * technology.
+ */
+ protected abstract ServletRequest getRequest();
+
+ /**
+ * This method allows subclasses to provide a way to access the ServletResponse according to the rendering
+ * technology.
+ */
+ protected abstract ServletResponse getResponse();
+
+ /**
+ * This method allows subclasses to provide a way to access the ServletContext according to the rendering
+ * technology.
+ */
+ protected abstract ServletContext getServletContext();
+
+ /**
+ * Make an authorization decision by considering all <authorize> tag attributes. The following are valid
+ * combinations of attributes:
+ *
+ * - access
+ * - url, method
+ * - ifAllGranted, ifAnyGranted, ifNotGranted
+ *
+ * The above combinations are mutually exclusive and evaluated in the given order.
+ *
+ * @return the result of the authorization decision
+ *
+ * @throws IOException
+ */
+ public boolean authorize() throws IOException {
+ boolean isAuthorized = false;
+
+ if (StringUtils.hasText(getAccess())) {
+ isAuthorized = authorizeUsingAccessExpression();
+
+ } else if (StringUtils.hasText(getUrl())) {
+ isAuthorized = authorizeUsingUrlCheck();
+
+ } else {
+ isAuthorized = authorizeUsingGrantedAuthorities();
+
+ }
+
+ return isAuthorized;
+ }
+
+ /**
+ * Make an authorization decision by considering ifAllGranted, ifAnyGranted, and ifNotGranted. All 3 or any
+ * combination can be provided. All provided attributes must evaluate to true.
+ *
+ * @return the result of the authorization decision
+ */
+ public boolean authorizeUsingGrantedAuthorities() {
+ boolean hasTextAllGranted = StringUtils.hasText(getIfAllGranted());
+ boolean hasTextAnyGranted = StringUtils.hasText(getIfAnyGranted());
+ boolean hasTextNotGranted = StringUtils.hasText(getIfNotGranted());
+
+ if ((!hasTextAllGranted) && (!hasTextAnyGranted) && (!hasTextNotGranted)) {
+ return false;
+ }
+
+ final Collection granted = getPrincipalAuthorities();
+
+ if (hasTextAllGranted) {
+ if (!granted.containsAll(parseAuthoritiesString(getIfAllGranted()))) {
+ return false;
+ }
+ }
+
+ if (hasTextAnyGranted) {
+ Set grantedCopy = retainAll(granted, parseAuthoritiesString(getIfAnyGranted()));
+ if (grantedCopy.isEmpty()) {
+ return false;
+ }
+ }
+
+ if (hasTextNotGranted) {
+ Set grantedCopy = retainAll(granted, parseAuthoritiesString(getIfNotGranted()));
+ if (!grantedCopy.isEmpty()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Make an authorization decision based on a Spring EL expression. See the "Expression-Based Access Control" chapter
+ * in Spring Security for details on what expressions can be used.
+ *
+ * @return the result of the authorization decision
+ *
+ * @throws IOException
+ */
+ public boolean authorizeUsingAccessExpression() throws IOException {
+ Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
+ if (currentUser == null) {
+ return false;
+ }
+
+ WebSecurityExpressionHandler handler = getExpressionHandler();
+
+ Expression accessExpression;
+ try {
+ accessExpression = handler.getExpressionParser().parseExpression(getAccess());
+
+ } catch (ParseException e) {
+ throw new IOException(e);
+ }
+
+ FilterInvocation f = new FilterInvocation(getRequest(), getResponse(), new FilterChain() {
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+ throw new UnsupportedOperationException();
+ }
+ });
+
+ return ExpressionUtils.evaluateAsBoolean(accessExpression, handler.createEvaluationContext(currentUser, f));
+ }
+
+ /**
+ * Make an authorization decision based on the URL and HTTP method attributes. True is returned if the user is
+ * allowed to access the given URL as defined.
+ *
+ * @return the result of the authorization decision
+ *
+ * @throws IOException
+ */
+ public boolean authorizeUsingUrlCheck() throws IOException {
+ String contextPath = ((HttpServletRequest) getRequest()).getContextPath();
+ Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
+ return getPrivilegeEvaluator().isAllowed(contextPath, getUrl(), getMethod(), currentUser);
+ }
+
+ public String getAccess() {
+ return access;
+ }
+
+ public void setAccess(String access) {
+ this.access = access;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public void setMethod(String method) {
+ this.method = (method != null) ? method.toUpperCase() : null;
+ }
+
+ public String getIfAllGranted() {
+ return ifAllGranted;
+ }
+
+ public void setIfAllGranted(String ifAllGranted) {
+ this.ifAllGranted = ifAllGranted;
+ }
+
+ public String getIfAnyGranted() {
+ return ifAnyGranted;
+ }
+
+ public void setIfAnyGranted(String ifAnyGranted) {
+ this.ifAnyGranted = ifAnyGranted;
+ }
+
+ public String getIfNotGranted() {
+ return ifNotGranted;
+ }
+
+ public void setIfNotGranted(String ifNotGranted) {
+ this.ifNotGranted = ifNotGranted;
+ }
+
+ /*------------- Private helper methods -----------------*/
+
+ private Collection getPrincipalAuthorities() {
+ Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
+ if (null == currentUser) {
+ return Collections.emptyList();
+ }
+ return currentUser.getAuthorities();
+ }
+
+ private Set parseAuthoritiesString(String authorizationsString) {
+ final Set requiredAuthorities = new HashSet();
+ requiredAuthorities.addAll(AuthorityUtils.commaSeparatedStringToAuthorityList(authorizationsString));
+ return requiredAuthorities;
+ }
+
+ 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 authoritiesToRoles(Collection c) {
+ Set target = new HashSet();
+ 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;
+ }
+
+ private Set rolesToAuthorities(Set grantedRoles, Collection granted) {
+ Set target = new HashSet();
+ for (String role : grantedRoles) {
+ for (GrantedAuthority authority : granted) {
+ if (authority.getAuthority().equals(role)) {
+ target.add(authority);
+ break;
+ }
+ }
+ }
+ return target;
+ }
+
+ private WebSecurityExpressionHandler getExpressionHandler() throws IOException {
+ ApplicationContext appContext = WebApplicationContextUtils
+ .getRequiredWebApplicationContext(getServletContext());
+ Map expressionHandlres = appContext
+ .getBeansOfType(WebSecurityExpressionHandler.class);
+
+ if (expressionHandlres.size() == 0) {
+ throw new IOException("No visible WebSecurityExpressionHandler instance could be found in the application "
+ + "context. There must be at least one in order to support expressions in JSP 'authorize' tags.");
+ }
+
+ return (WebSecurityExpressionHandler) expressionHandlres.values().toArray()[0];
+ }
+
+ private WebInvocationPrivilegeEvaluator getPrivilegeEvaluator() throws IOException {
+ ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
+ Map wipes = ctx.getBeansOfType(WebInvocationPrivilegeEvaluator.class);
+
+ if (wipes.size() == 0) {
+ throw new IOException(
+ "No visible WebInvocationPrivilegeEvaluator instance could be found in the application "
+ + "context. There must be at least one in order to support the use of URL access checks in 'authorize' tags.");
+ }
+
+ return (WebInvocationPrivilegeEvaluator) wipes.values().toArray()[0];
+ }
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTag.java b/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTag.java
new file mode 100644
index 00000000..9313b24d
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTag.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2004-2010 the original author or authors.
+ *
+ * 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.faces.security;
+
+import javax.el.ValueExpression;
+import javax.faces.context.FacesContext;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagHandler;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * A concrete implementation of {@link AbstractAuthorizeTag} for use with standard Facelets rendering technology (JSF 2
+ * or higher).
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.2.0
+ */
+public class FaceletsAuthorizeTag extends AbstractAuthorizeTag {
+
+ /**
+ * A class constructor for use in a {@link TagHandler}. Accepts all possible tag attributes as {@link TagAttribute}
+ * instances. The constructor extracts the attribute values by evaluating them as Unified EL expressions. This
+ * excludes the access attribute, which is expected to be a Spring EL expression.
+ *
+ * @param faceletContext the current FaceletContext
+ * @param access the access attribute or null
+ * @param url the url attribute or null
+ * @param method the method attribute or null
+ * @param ifAllGranted the ifAllGranted attribute or null
+ * @param ifAnyGranted the ifAnyGranted attribute or null
+ * @param ifNotGranted the ifNotGranted attribute or null
+ */
+ public FaceletsAuthorizeTag(FaceletContext faceletContext, TagAttribute access, TagAttribute url,
+ TagAttribute method, TagAttribute ifAllGranted, TagAttribute ifAnyGranted, TagAttribute ifNotGranted) {
+ setAccess(getAttributeValue(faceletContext, access, false));
+ setUrl(getAttributeValue(faceletContext, url, true));
+ setMethod(getAttributeValue(faceletContext, method, true));
+ setIfAllGranted(getAttributeValue(faceletContext, ifAllGranted, true));
+ setIfAnyGranted(getAttributeValue(faceletContext, ifAnyGranted, true));
+ setIfNotGranted(getAttributeValue(faceletContext, ifNotGranted, true));
+ }
+
+ /**
+ * A default constructor. Callers of this constructor are responsible for setting one or more of the tag attributes
+ * in {@link AbstractAuthorizeTag}.
+ */
+ public FaceletsAuthorizeTag() {
+ }
+
+ protected ServletRequest getRequest() {
+ return (ServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
+ }
+
+ protected ServletResponse getResponse() {
+ return (ServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
+ }
+
+ protected ServletContext getServletContext() {
+ return (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
+ }
+
+ /*---- Pirvate helper methods ----*/
+
+ private String getAttributeValue(FaceletContext faceletContext, TagAttribute tagAttribute, boolean evaluate) {
+ String value = null;
+ if (tagAttribute != null) {
+ if (evaluate) {
+ ValueExpression expression = tagAttribute.getValueExpression(faceletContext, String.class);
+ value = (String) expression.getValue(faceletContext.getFacesContext().getELContext());
+ } else {
+ value = tagAttribute.getValue();
+ }
+ }
+ return value;
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagHandler.java b/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagHandler.java
new file mode 100644
index 00000000..4ed8fa91
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagHandler.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2004-2010 the original author or authors.
+ *
+ * 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.faces.security;
+
+import java.io.IOException;
+
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagHandler;
+
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/**
+ * A standard Facelets {@link TagHandler} for performing Spring Security authorization decisions. The tag supports the
+ * following combinations attributes for authorization:
+ *
+ * - access
+ * - url, method
+ * - ifAllGranted, ifAnyGranted, ifNotGranted
+ *
+ * The var attribute can be used to store the result of the authorization decision for later use in the view.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.2.0
+ * @see FaceletsAuthorizeTag
+ */
+public class FaceletsAuthorizeTagHandler extends TagHandler {
+
+ private final TagAttribute access;
+ private final TagAttribute url;
+ private final TagAttribute method;
+ private final TagAttribute ifAllGranted;
+ private final TagAttribute ifAnyGranted;
+ private final TagAttribute ifNotGranted;
+ private final TagAttribute var;
+
+ /**
+ * @see TagHandler#TagHandler(TagConfig)
+ */
+ public FaceletsAuthorizeTagHandler(TagConfig config) {
+ super(config);
+ this.access = this.getAttribute("access");
+ this.url = this.getAttribute("url");
+ this.method = this.getAttribute("method");
+ this.ifAllGranted = this.getAttribute("ifAllGranted");
+ this.ifAnyGranted = this.getAttribute("ifAnyGranted");
+ this.ifNotGranted = this.getAttribute("ifNotGranted");
+ this.var = this.getAttribute("var");
+ }
+
+ /**
+ * @see TagHandler#apply(FaceletContext, UIComponent)
+ */
+ public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException {
+ if (SecurityContextHolder.getContext().getAuthentication() == null) {
+ return;
+ }
+
+ FaceletsAuthorizeTag authorizeTag = new FaceletsAuthorizeTag(faceletContext, access, url, method, ifAllGranted,
+ ifAnyGranted, ifNotGranted);
+
+ boolean isAuthorized = authorizeTag.authorize();
+
+ if (isAuthorized) {
+ this.nextHandler.apply(faceletContext, parent);
+ }
+
+ if (this.var != null) {
+ faceletContext.setAttribute(var.getValue(faceletContext), Boolean.valueOf(isAuthorized));
+ }
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagUtils.java b/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagUtils.java
new file mode 100644
index 00000000..250e3467
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagUtils.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2004-2010 the original author or authors.
+ *
+ * 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.faces.security;
+
+import java.io.IOException;
+
+/**
+ * This class provides static methods that are registered as EL functions and available for use in Unified EL
+ * expressions in standard Facelets views (JSF 2 or higher).
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.2.0
+ */
+public abstract class FaceletsAuthorizeTagUtils {
+
+ /**
+ * Returns true if the user has all of of the given authorities.
+ *
+ * @param authorities a comma-separated list of user authorities.
+ */
+ public static boolean areAllGranted(String authorities) throws IOException {
+ FaceletsAuthorizeTag authorizeTag = new FaceletsAuthorizeTag();
+ authorizeTag.setIfAllGranted(authorities);
+ return authorizeTag.authorizeUsingGrantedAuthorities();
+ }
+
+ /**
+ * Returns true if the user has any of the given authorities.
+ *
+ * @param authorities a comma-separated list of user authorities.
+ */
+ public static boolean areAnyGranted(String authorities) throws IOException {
+ FaceletsAuthorizeTag authorizeTag = new FaceletsAuthorizeTag();
+ authorizeTag.setIfAnyGranted(authorities);
+ return authorizeTag.authorizeUsingGrantedAuthorities();
+ }
+
+ /**
+ * Returns true if the user does not have any of the given authorities.
+ *
+ * @param authorities a comma-separated list of user authorities.
+ */
+ public static boolean areNotGranted(String authorities) throws IOException {
+ FaceletsAuthorizeTag authorizeTag = new FaceletsAuthorizeTag();
+ authorizeTag.setIfNotGranted(authorities);
+ return authorizeTag.authorizeUsingGrantedAuthorities();
+ }
+
+ /**
+ * Returns true if the user is allowed to access the given URL and HTTP method combination. The HTTP method is
+ * optional and case insensitive.
+ */
+ public static boolean isAllowed(String url, String method) throws IOException {
+ FaceletsAuthorizeTag authorizeTag = new FaceletsAuthorizeTag();
+ authorizeTag.setUrl(url);
+ authorizeTag.setMethod(method);
+ return authorizeTag.authorizeUsingUrlCheck();
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTag.java b/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTag.java
new file mode 100644
index 00000000..8f6e04d8
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTag.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2004-2010 the original author or authors.
+ *
+ * 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.faces.security;
+
+import javax.el.ValueExpression;
+import javax.faces.context.FacesContext;
+import javax.faces.view.facelets.TagHandler;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import com.sun.facelets.FaceletContext;
+import com.sun.facelets.tag.TagAttribute;
+
+/**
+ * A concrete implementation of {@link AbstractAuthorizeTag} for use with Facelets rendering technology in JSF 1.2
+ * environments.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.2.0
+ * @see FaceletsAuthorizeTag
+ */
+public class Jsf12FaceletsAuthorizeTag extends AbstractAuthorizeTag {
+
+ /**
+ * A class constructor for use in a {@link TagHandler}. Accepts all possible tag attributes as {@link TagAttribute}
+ * instances. The constructor extracts the attribute values by evaluating them as Unified EL expressions. This
+ * excludes the access attribute, which is expected to be a Spring EL expression.
+ *
+ * @param faceletContext the current FaceletContext
+ * @param access the access attribute or null
+ * @param url the url attribute or null
+ * @param method the method attribute or null
+ * @param ifAllGranted the ifAllGranted attribute or null
+ * @param ifAnyGranted the ifAnyGranted attribute or null
+ * @param ifNotGranted the ifNotGranted attribute or null
+ */
+ public Jsf12FaceletsAuthorizeTag(FaceletContext faceletContext, TagAttribute access, TagAttribute url,
+ TagAttribute method, TagAttribute ifAllGranted, TagAttribute ifAnyGranted, TagAttribute ifNotGranted) {
+ setAccess(getAttributeValue(faceletContext, access, false));
+ setUrl(getAttributeValue(faceletContext, url, true));
+ setMethod(getAttributeValue(faceletContext, method, true));
+ setIfAllGranted(getAttributeValue(faceletContext, ifAllGranted, true));
+ setIfAnyGranted(getAttributeValue(faceletContext, ifAnyGranted, true));
+ setIfNotGranted(getAttributeValue(faceletContext, ifNotGranted, true));
+ }
+
+ /**
+ * A default constructor. Callers of this constructor are responsible for setting one or more of the tag attributes
+ * in {@link AbstractAuthorizeTag}.
+ */
+ public Jsf12FaceletsAuthorizeTag() {
+ }
+
+ protected ServletRequest getRequest() {
+ return (ServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
+ }
+
+ protected ServletResponse getResponse() {
+ return (ServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
+ }
+
+ protected ServletContext getServletContext() {
+ return (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
+ }
+
+ /*---- Pirvate helper methods ----*/
+
+ private String getAttributeValue(FaceletContext faceletContext, TagAttribute tagAttribute, boolean evaluate) {
+ String value = null;
+ if (tagAttribute != null) {
+ if (evaluate) {
+ ValueExpression expression = tagAttribute.getValueExpression(faceletContext, String.class);
+ value = (String) expression.getValue(faceletContext.getFacesContext().getELContext());
+ } else {
+ value = tagAttribute.getValue();
+ }
+ }
+ return value;
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagHandler.java b/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagHandler.java
new file mode 100644
index 00000000..180ab85a
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagHandler.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2004-2010 the original author or authors.
+ *
+ * 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.faces.security;
+
+import java.io.IOException;
+
+import javax.faces.component.UIComponent;
+
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import com.sun.facelets.FaceletContext;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.TagConfig;
+import com.sun.facelets.tag.TagHandler;
+
+/**
+ * A JSF 1.2 Facelets {@link TagHandler} for performing Spring Security authorization decisions. The tag supports the
+ * following combinations attributes for authorization:
+ *
+ * - access
+ * - url, method
+ * - ifAllGranted, ifAnyGranted, ifNotGranted
+ *
+ * The var attribute can be used to store the result of the authorization decision for later use in the view.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.2.0
+ * @see Jsf12FaceletsAuthorizeTag
+ */
+public class Jsf12FaceletsAuthorizeTagHandler extends TagHandler {
+
+ private final TagAttribute access;
+ private final TagAttribute url;
+ private final TagAttribute method;
+ private final TagAttribute ifAllGranted;
+ private final TagAttribute ifAnyGranted;
+ private final TagAttribute ifNotGranted;
+ private final TagAttribute var;
+
+ /**
+ * @see TagHandler#TagHandler(TagConfig)
+ */
+ public Jsf12FaceletsAuthorizeTagHandler(TagConfig config) {
+ super(config);
+ this.access = this.getAttribute("access");
+ this.url = this.getAttribute("url");
+ this.method = this.getAttribute("method");
+ this.ifAllGranted = this.getAttribute("ifAllGranted");
+ this.ifAnyGranted = this.getAttribute("ifAnyGranted");
+ this.ifNotGranted = this.getAttribute("ifNotGranted");
+ this.var = this.getAttribute("var");
+ }
+
+ /**
+ * @see TagHandler#apply(FaceletContext, UIComponent)
+ */
+ public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException {
+ if (SecurityContextHolder.getContext().getAuthentication() == null) {
+ return;
+ }
+
+ Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag(faceletContext, access, url, method,
+ ifAllGranted, ifAnyGranted, ifNotGranted);
+
+ boolean isAuthorized = authorizeTag.authorize();
+
+ if (isAuthorized) {
+ this.nextHandler.apply(faceletContext, parent);
+ }
+
+ if (this.var != null) {
+ faceletContext.setAttribute(var.getValue(faceletContext), Boolean.valueOf(isAuthorized));
+ }
+
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagUtils.java b/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagUtils.java
new file mode 100644
index 00000000..7f98e5ca
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagUtils.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2004-2010 the original author or authors.
+ *
+ * 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.faces.security;
+
+import java.io.IOException;
+
+/**
+ * This class provides static methods that are registered as EL functions and available for use in Unified EL
+ * expressions in JSF 1.2 Facelets views.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.2.0
+ */
+public abstract class Jsf12FaceletsAuthorizeTagUtils {
+
+ /**
+ * Returns true if the user has all of of the given authorities.
+ *
+ * @param authorities a comma-separated list of user authorities.
+ */
+ public static boolean areAllGranted(String authorities) throws IOException {
+ Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag();
+ authorizeTag.setIfAllGranted(authorities);
+ return authorizeTag.authorizeUsingGrantedAuthorities();
+ }
+
+ /**
+ * Returns true if the user has any of the given authorities.
+ *
+ * @param authorities a comma-separated list of user authorities.
+ */
+ public static boolean areAnyGranted(String authorities) throws IOException {
+ Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag();
+ authorizeTag.setIfAnyGranted(authorities);
+ return authorizeTag.authorizeUsingGrantedAuthorities();
+ }
+
+ /**
+ * Returns true if the user does not have any of the given authorities.
+ *
+ * @param authorities a comma-separated list of user authorities.
+ */
+ public static boolean areNotGranted(String authorities) throws IOException {
+ Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag();
+ authorizeTag.setIfNotGranted(authorities);
+ return authorizeTag.authorizeUsingGrantedAuthorities();
+ }
+
+ /**
+ * Returns true if the user is allowed to access the given URL and HTTP method combination. The HTTP method is
+ * optional and case insensitive.
+ */
+ public static boolean isAllowed(String url, String method) throws IOException {
+ Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag();
+ authorizeTag.setUrl(url);
+ authorizeTag.setMethod(method);
+ return authorizeTag.authorizeUsingUrlCheck();
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/security/SpringSecurityTagLibrary.java b/spring-faces/src/main/java/org/springframework/faces/security/SpringSecurityTagLibrary.java
new file mode 100644
index 00000000..f875e538
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/security/SpringSecurityTagLibrary.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2004-2010 the original author or authors.
+ *
+ * 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.faces.security;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.springframework.faces.webflow.JsfRuntimeInformation;
+
+import com.sun.faces.facelets.tag.AbstractTagLibrary;
+
+/**
+ * Registers a tag handler for the <authorize> tag and several EL functions that can be used on any component that
+ * accepts EL expressions in its attributes. For details on the EL functions see {@link FaceletsAuthorizeTagUtils} or
+ * {@link Jsf12FaceletsAuthorizeTagUtils} depending on your environment.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.2.0
+ * @see FaceletsAuthorizeTagHandler
+ * @see FaceletsAuthorizeTagUtils
+ */
+public class SpringSecurityTagLibrary extends AbstractTagLibrary {
+
+ public static final String NAMESPACE = "http://www.springframework.org/security/tags";
+
+ public SpringSecurityTagLibrary() {
+ super(NAMESPACE);
+
+ if (JsfRuntimeInformation.isAtLeastJsf20()) {
+ this.addTagHandler("authorize", FaceletsAuthorizeTagHandler.class);
+ } else {
+ this.addTagHandler("authorize", Jsf12FaceletsAuthorizeTagHandler.class);
+ }
+
+ try {
+ Method[] methods = (JsfRuntimeInformation.isAtLeastJsf20()) ? FaceletsAuthorizeTagUtils.class.getMethods()
+ : Jsf12FaceletsAuthorizeTagUtils.class.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ if (Modifier.isStatic(methods[i].getModifiers())) {
+ this.addFunction(methods[i].getName(), methods[i]);
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java b/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java
index 6a87eff2..e74541f4 100644
--- a/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java
+++ b/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java
@@ -1,10 +1,10 @@
/*
- * Copyright 2004-2008 the original authorimport javax.faces.event.PhaseEvent;
-import javax.faces.event.PhaseId;
-import javax.faces.event.PhaseListener;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+ * Copyright 2004-2008 the original author or authors.
+ *
+ * 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
diff --git a/spring-faces/src/main/resources/META-INF/springsecurity.taglib.xml b/spring-faces/src/main/resources/META-INF/springsecurity.taglib.xml
new file mode 100644
index 00000000..5455cb2f
--- /dev/null
+++ b/spring-faces/src/main/resources/META-INF/springsecurity.taglib.xml
@@ -0,0 +1,7 @@
+
+
+
+ org.springframework.faces.security.SpringSecurityTagLibrary
+
\ No newline at end of file