Author: remy.maucherat(a)jboss.com
Date: 2009-06-12 11:53:50 -0400 (Fri, 12 Jun 2009)
New Revision: 1111
Modified:
trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
Log:
- Process JSR250 access control annotations.
Modified: trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
===================================================================
--- trunk/java/org/apache/catalina/startup/WebAnnotationSet.java 2009-06-12 11:46:42 UTC
(rev 1110)
+++ trunk/java/org/apache/catalina/startup/WebAnnotationSet.java 2009-06-12 15:53:50 UTC
(rev 1111)
@@ -19,13 +19,26 @@
package org.apache.catalina.startup;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+
import javax.annotation.Resource;
import javax.annotation.Resources;
import javax.annotation.security.DeclareRoles;
+import javax.annotation.security.DenyAll;
+import javax.annotation.security.PermitAll;
+import javax.annotation.security.RolesAllowed;
import javax.annotation.security.RunAs;
+import javax.annotation.security.TransportProtected;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
import org.apache.catalina.core.StandardWrapper;
import org.apache.catalina.deploy.ContextEnvironment;
import org.apache.catalina.deploy.ContextResource;
@@ -33,6 +46,8 @@
import org.apache.catalina.deploy.ContextService;
import org.apache.catalina.deploy.FilterDef;
import org.apache.catalina.deploy.MessageDestinationRef;
+import org.apache.catalina.deploy.SecurityCollection;
+import org.apache.catalina.deploy.SecurityConstraint;
/**
* <p><strong>AnnotationSet</strong> for processing the annotations of
the web application
@@ -57,7 +72,6 @@
loadApplicationFilterAnnotations(context);
loadApplicationServletAnnotations(context);
-
}
@@ -118,16 +132,139 @@
loadClassAnnotation(context, wrapper.getServletClass());
- // FIXME: Parse the other access control annotations
- /* Process RunAs annotation which can be only on servlets.
- * Ref JSR 250, equivalent to the run-as element in
- * the deployment descriptor
- */
+ // Process JSR 250 access control annotations
+ // Process PermitAll, TransportProtected and RolesAllowed on the class
+ boolean classPA = false, classTP = false;
+ String[] classRA = null;
+ ArrayList<String> methodOmissions = new ArrayList<String>();
+ if (classClass.isAnnotationPresent(PermitAll.class)) {
+ classPA = true;
+ }
+ if (classClass.isAnnotationPresent(TransportProtected.class)) {
+ TransportProtected annotation = (TransportProtected)
+ classClass.getAnnotation(TransportProtected.class);
+ classTP = annotation.value();
+ }
+ if (classClass.isAnnotationPresent(RolesAllowed.class)) {
+ RolesAllowed annotation = (RolesAllowed)
+ classClass.getAnnotation(RolesAllowed.class);
+ classRA = annotation.value();
+ }
if (classClass.isAnnotationPresent(RunAs.class)) {
RunAs annotation = (RunAs)
classClass.getAnnotation(RunAs.class);
wrapper.setRunAs(annotation.value());
}
+
+ // Process HttpServlet methods annotations
+ if (HttpServlet.class.isAssignableFrom(classClass)) {
+
+ Method[] methods = null;
+ final Class<?> classClass2 = classClass;
+ if (Globals.IS_SECURITY_ENABLED) {
+ methods = AccessController.doPrivileged(
+ new PrivilegedAction<Method[]>(){
+ public Method[] run(){
+ return classClass2.getDeclaredMethods();
+ }
+ });
+ } else {
+ methods = classClass.getDeclaredMethods();
+ }
+ for (Method method : methods) {
+ if (!((method.getParameterTypes().length == 2)
+ && (method.getParameterTypes()[0] ==
HttpServletRequest.class)
+ && (method.getParameterTypes()[1] ==
HttpServletResponse.class))) {
+ continue;
+ }
+ String methodName = null;
+ if (method.getName().startsWith("do")) {
+ methodName = method.getName().substring(2).toUpperCase();
+ }
+ if (methodName == null) {
+ continue;
+ }
+ boolean methodAnnotation = false;
+ boolean methodPA = false, methodDA = false, methodTP = false;
+ String[] methodRA = null;
+ if (method.isAnnotationPresent(PermitAll.class)) {
+ methodPA = true;
+ methodAnnotation = true;
+ }
+ if (method.isAnnotationPresent(DenyAll.class)) {
+ methodDA = true;
+ methodAnnotation = true;
+ }
+ if (method.isAnnotationPresent(TransportProtected.class)) {
+ TransportProtected annotation = (TransportProtected)
+ method.getAnnotation(TransportProtected.class);
+ methodTP = annotation.value();
+ methodAnnotation = true;
+ }
+ if (method.isAnnotationPresent(RolesAllowed.class)) {
+ RolesAllowed annotation = (RolesAllowed)
+ method.getAnnotation(RolesAllowed.class);
+ methodRA = annotation.value();
+ methodAnnotation = true;
+ }
+ if (methodAnnotation) {
+ methodOmissions.add(methodName);
+ // Define a constraint specific for the method
+ SecurityConstraint constraint = new SecurityConstraint();
+ if (methodDA) {
+ constraint.setAuthConstraint(true);
+ }
+ if (methodPA) {
+ constraint.addAuthRole("*");
+ }
+ if (methodRA != null) {
+ for (String role : methodRA) {
+ constraint.addAuthRole(role);
+ }
+ }
+ if (methodTP) {
+
constraint.setUserConstraint(org.apache.catalina.realm.Constants.CONFIDENTIAL_TRANSPORT);
+ }
+ SecurityCollection collection = new SecurityCollection();
+ collection.addMethod(methodName);
+ String[] urlPatterns = wrapper.findMappings();
+ for (String urlPattern : urlPatterns) {
+ collection.addPattern(urlPattern);
+ }
+ constraint.addCollection(collection);
+ context.addConstraint(constraint);
+ }
+
+ }
+
+ }
+
+ if (classPA || classTP || classRA != null) {
+ // Define a constraint for the class
+ SecurityConstraint constraint = new SecurityConstraint();
+ if (classPA) {
+ constraint.addAuthRole("*");
+ }
+ if (classRA != null) {
+ for (String role : classRA) {
+ constraint.addAuthRole(role);
+ }
+ }
+ if (classTP) {
+
constraint.setUserConstraint(org.apache.catalina.realm.Constants.CONFIDENTIAL_TRANSPORT);
+ }
+ SecurityCollection collection = new SecurityCollection();
+ String[] urlPatterns = wrapper.findMappings();
+ for (String urlPattern : urlPatterns) {
+ collection.addPattern(urlPattern);
+ }
+ for (String methodOmission : methodOmissions) {
+ collection.addMethodOmission(methodOmission);
+ }
+ constraint.addCollection(collection);
+ context.addConstraint(constraint);
+ }
+
}
}
Show replies by date