Save This Page
Home » Tomcat-6.0.20 » org.apache » catalina » security » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.catalina.security;
   18   
   19   
   20   import java.io.IOException;
   21   import java.lang.reflect.InvocationTargetException;
   22   import java.lang.reflect.Method;
   23   import java.security.Principal;
   24   import java.security.PrivilegedActionException;
   25   import java.security.PrivilegedExceptionAction;
   26   import java.util.HashMap;
   27   
   28   import javax.security.auth.Subject;
   29   import javax.servlet.Filter;
   30   import javax.servlet.Servlet;
   31   import javax.servlet.ServletException;
   32   import javax.servlet.UnavailableException;
   33   import javax.servlet.http.HttpServletRequest;
   34   import javax.servlet.http.HttpSession;
   35   
   36   import org.apache.catalina.Globals;
   37   import org.apache.catalina.util.StringManager;
   38   /**
   39    * This utility class associates a <code>Subject</code> to the current 
   40    * <code>AccessControlContext</code>. When a <code>SecurityManager</code> is
   41    * used, * the container will always associate the called thread with an 
   42    * AccessControlContext * containing only the principal of the requested
   43    * Servlet/Filter.
   44    *
   45    * This class uses reflection to invoke the invoke methods.
   46    *
   47    * @author Jean-Francois Arcand
   48    */
   49   
   50   public final class SecurityUtil{
   51       
   52       private final static int INIT= 0;
   53       private final static int SERVICE = 1;
   54       private final static int DOFILTER = 1;
   55       private final static int DESTROY = 2;
   56       
   57       private final static String INIT_METHOD = "init";
   58       private final static String DOFILTER_METHOD = "doFilter";
   59       private final static String SERVICE_METHOD = "service";
   60       private final static String DESTROY_METHOD = "destroy";
   61      
   62       /**
   63        * Cache every object for which we are creating method on it.
   64        */
   65       private static HashMap objectCache = new HashMap();
   66           
   67       private static org.apache.juli.logging.Log log=
   68           org.apache.juli.logging.LogFactory.getLog( SecurityUtil.class );
   69       
   70       private static String PACKAGE = "org.apache.catalina.security";
   71       
   72       private static boolean packageDefinitionEnabled =  
   73            (System.getProperty("package.definition") == null && 
   74              System.getProperty("package.access")  == null) ? false : true;
   75       
   76       /**
   77        * The string resources for this package.
   78        */
   79       private static final StringManager sm =
   80           StringManager.getManager(PACKAGE);    
   81       
   82       
   83       /**
   84        * Perform work as a particular </code>Subject</code>. Here the work
   85        * will be granted to a <code>null</code> subject. 
   86        *
   87        * @param methodName the method to apply the security restriction
   88        * @param targetObject the <code>Servlet</code> on which the method will
   89        * be called.
   90        */
   91       public static void doAsPrivilege(final String methodName, 
   92                                        final Servlet targetObject) throws java.lang.Exception{
   93            doAsPrivilege(methodName, targetObject, null, null, null);                                
   94       }
   95   
   96       
   97       /**
   98        * Perform work as a particular </code>Subject</code>. Here the work
   99        * will be granted to a <code>null</code> subject. 
  100        *
  101        * @param methodName the method to apply the security restriction
  102        * @param targetObject the <code>Servlet</code> on which the method will
  103        * be called.
  104        * @param targetType <code>Class</code> array used to instanciate a i
  105        * <code>Method</code> object.
  106        * @param targetArguments <code>Object</code> array contains the runtime 
  107        * parameters instance.
  108        */
  109       public static void doAsPrivilege(final String methodName, 
  110                                        final Servlet targetObject, 
  111                                        final Class[] targetType,
  112                                        final Object[] targetArguments) 
  113           throws java.lang.Exception{    
  114   
  115            doAsPrivilege(methodName, 
  116                          targetObject, 
  117                          targetType, 
  118                          targetArguments, 
  119                          null);                                
  120       }
  121       
  122       
  123       /**
  124        * Perform work as a particular </code>Subject</code>. Here the work
  125        * will be granted to a <code>null</code> subject. 
  126        *
  127        * @param methodName the method to apply the security restriction
  128        * @param targetObject the <code>Servlet</code> on which the method will
  129        * be called.
  130        * @param targetType <code>Class</code> array used to instanciate a 
  131        * <code>Method</code> object.
  132        * @param targetArguments <code>Object</code> array contains the 
  133        * runtime parameters instance.
  134        * @param principal the <code>Principal</code> to which the security 
  135        * privilege apply..
  136        */    
  137       public static void doAsPrivilege(final String methodName, 
  138                                        final Servlet targetObject, 
  139                                        final Class[] targetType,
  140                                        final Object[] targetArguments,
  141                                        Principal principal) 
  142           throws java.lang.Exception{
  143   
  144           Method method = null;
  145           Method[] methodsCache = null;
  146           if(objectCache.containsKey(targetObject)){
  147               methodsCache = (Method[])objectCache.get(targetObject);
  148               method = findMethod(methodsCache, methodName);
  149               if (method == null){
  150                   method = createMethodAndCacheIt(methodsCache,
  151                                                   methodName,
  152                                                   targetObject,
  153                                                   targetType);
  154               }
  155           } else {
  156               method = createMethodAndCacheIt(methodsCache,
  157                                               methodName,
  158                                               targetObject,
  159                                               targetType);                     
  160           }
  161   
  162           execute(method, targetObject, targetArguments, principal);
  163       }
  164    
  165       
  166       /**
  167        * Perform work as a particular </code>Subject</code>. Here the work
  168        * will be granted to a <code>null</code> subject. 
  169        *
  170        * @param methodName the method to apply the security restriction
  171        * @param targetObject the <code>Filter</code> on which the method will 
  172        * be called.
  173        */    
  174       public static void doAsPrivilege(final String methodName, 
  175                                        final Filter targetObject) 
  176           throws java.lang.Exception{
  177   
  178            doAsPrivilege(methodName, targetObject, null, null);                                
  179       }
  180    
  181       
  182       /**
  183        * Perform work as a particular <code>Subject</code>. Here the work
  184        * will be granted to a <code>null</code> subject. 
  185        *
  186        * @param methodName the method to apply the security restriction
  187        * @param targetObject the <code>Filter</code> on which the method will 
  188        * be called.
  189        * @param targetType <code>Class</code> array used to instanciate a
  190        * <code>Method</code> object.
  191        * @param targetArguments <code>Object</code> array contains the 
  192        * runtime parameters instance.
  193        */    
  194       public static void doAsPrivilege(final String methodName, 
  195                                        final Filter targetObject, 
  196                                        final Class[] targetType,
  197                                        final Object[] targetArguments) 
  198           throws java.lang.Exception{
  199   
  200           doAsPrivilege(
  201                   methodName, targetObject, targetType, targetArguments, null);
  202       }
  203       
  204       /**
  205        * Perform work as a particular <code>Subject</code>. Here the work
  206        * will be granted to a <code>null</code> subject. 
  207        *
  208        * @param methodName the method to apply the security restriction
  209        * @param targetObject the <code>Filter</code> on which the method will 
  210        * be called.
  211        * @param targetType <code>Class</code> array used to instanciate a
  212        * <code>Method</code> object.
  213        * @param targetArguments <code>Object</code> array contains the 
  214        * runtime parameters instance.
  215        * @param principal the <code>Principal</code> to which the security 
  216        * privilege apply
  217        */    
  218       public static void doAsPrivilege(final String methodName, 
  219                                        final Filter targetObject, 
  220                                        final Class[] targetType,
  221                                        final Object[] targetArguments,
  222                                        Principal principal) 
  223           throws java.lang.Exception{
  224           Method method = null;
  225   
  226           Method[] methodsCache = null;
  227           if(objectCache.containsKey(targetObject)){
  228               methodsCache = (Method[])objectCache.get(targetObject);
  229               method = findMethod(methodsCache, methodName);
  230               if (method == null){
  231                   method = createMethodAndCacheIt(methodsCache,
  232                                                   methodName,
  233                                                   targetObject,
  234                                                   targetType);
  235               }
  236           } else {
  237               method = createMethodAndCacheIt(methodsCache,
  238                                               methodName,
  239                                               targetObject,
  240                                               targetType);                     
  241           }
  242   
  243           execute(method, targetObject, targetArguments, principal);
  244       }
  245       
  246       
  247       /**
  248        * Perform work as a particular </code>Subject</code>. Here the work
  249        * will be granted to a <code>null</code> subject. 
  250        *
  251        * @param methodName the method to apply the security restriction
  252        * @param targetObject the <code>Servlet</code> on which the method will
  253        * be called.
  254        * @param targetArguments <code>Object</code> array contains the 
  255        * runtime parameters instance.
  256        * @param principal the <code>Principal</code> to which the security 
  257        * privilege applies
  258        */    
  259       private static void execute(final Method method,
  260                                   final Object targetObject, 
  261                                   final Object[] targetArguments,
  262                                   Principal principal) 
  263           throws java.lang.Exception{
  264          
  265           try{   
  266               Subject subject = null;
  267               PrivilegedExceptionAction pea = new PrivilegedExceptionAction(){
  268                       public Object run() throws Exception{
  269                          method.invoke(targetObject, targetArguments);
  270                          return null;
  271                       }
  272               };
  273   
  274               // The first argument is always the request object
  275               if (targetArguments != null 
  276                       && targetArguments[0] instanceof HttpServletRequest){
  277                   HttpServletRequest request = 
  278                       (HttpServletRequest)targetArguments[0];
  279   
  280                   boolean hasSubject = false;
  281                   HttpSession session = request.getSession(false);
  282                   if (session != null){
  283                       subject = 
  284                           (Subject)session.getAttribute(Globals.SUBJECT_ATTR);
  285                       hasSubject = (subject != null);
  286                   }
  287   
  288                   if (subject == null){
  289                       subject = new Subject();
  290                       
  291                       if (principal != null){
  292                           subject.getPrincipals().add(principal);
  293                       }
  294                   }
  295   
  296                   if (session != null && !hasSubject) {
  297                       session.setAttribute(Globals.SUBJECT_ATTR, subject);
  298                   }
  299               }
  300   
  301               Subject.doAsPrivileged(subject, pea, null);       
  302           } catch( PrivilegedActionException pe) {
  303               Throwable e;
  304               if (pe.getException() instanceof InvocationTargetException) {
  305                   e = ((InvocationTargetException)pe.getException())
  306                                   .getTargetException();
  307               } else {
  308                   e = pe;
  309               }
  310               
  311               if (log.isDebugEnabled()){
  312                   log.debug(sm.getString("SecurityUtil.doAsPrivilege"), e); 
  313               }
  314               
  315               if (e instanceof UnavailableException)
  316                   throw (UnavailableException) e;
  317               else if (e instanceof ServletException)
  318                   throw (ServletException) e;
  319               else if (e instanceof IOException)
  320                   throw (IOException) e;
  321               else if (e instanceof RuntimeException)
  322                   throw (RuntimeException) e;
  323               else
  324                   throw new ServletException(e.getMessage(), e);
  325           }  
  326       }
  327       
  328       
  329       /**
  330        * Find a method stored within the cache.
  331        * @param methodsCache the cache used to store method instance
  332        * @param methodName the method to apply the security restriction
  333        * @return the method instance, null if not yet created.
  334        */
  335       private static Method findMethod(Method[] methodsCache,
  336                                        String methodName){
  337           if (methodName.equalsIgnoreCase(INIT_METHOD) 
  338                   && methodsCache[INIT] != null){
  339               return methodsCache[INIT];
  340           } else if (methodName.equalsIgnoreCase(DESTROY_METHOD) 
  341                   && methodsCache[DESTROY] != null){
  342               return methodsCache[DESTROY];            
  343           } else if (methodName.equalsIgnoreCase(SERVICE_METHOD) 
  344                   && methodsCache[SERVICE] != null){
  345               return methodsCache[SERVICE];
  346           } else if (methodName.equalsIgnoreCase(DOFILTER_METHOD) 
  347                   && methodsCache[DOFILTER] != null){
  348               return methodsCache[DOFILTER];          
  349           } 
  350           return null;
  351       }
  352       
  353       
  354       /**
  355        * Create the method and cache it for further re-use.
  356        * @param methodsCache the cache used to store method instance
  357        * @param methodName the method to apply the security restriction
  358        * @param targetObject the <code>Servlet</code> on which the method will
  359        * be called.
  360        * @param targetType <code>Class</code> array used to instanciate a 
  361        * <code>Method</code> object.
  362        * @return the method instance.
  363        */
  364       private static Method createMethodAndCacheIt(Method[] methodsCache,
  365                                                    String methodName,
  366                                                    Object targetObject,
  367                                                    Class[] targetType) 
  368               throws Exception{
  369           
  370           if ( methodsCache == null){
  371               methodsCache = new Method[3];
  372           }               
  373                   
  374           Method method = 
  375               targetObject.getClass().getMethod(methodName, targetType); 
  376   
  377           if (methodName.equalsIgnoreCase(INIT_METHOD)){
  378               methodsCache[INIT] = method;
  379           } else if (methodName.equalsIgnoreCase(DESTROY_METHOD)){
  380               methodsCache[DESTROY] = method;
  381           } else if (methodName.equalsIgnoreCase(SERVICE_METHOD)){
  382               methodsCache[SERVICE] = method;
  383           } else if (methodName.equalsIgnoreCase(DOFILTER_METHOD)){
  384               methodsCache[DOFILTER] = method;
  385           } 
  386            
  387           objectCache.put(targetObject, methodsCache );
  388                                              
  389           return method;
  390       }
  391   
  392       
  393       /**
  394        * Remove the object from the cache.
  395        *
  396        * @param cachedObject The object to remove
  397        */
  398       public static void remove(Object cachedObject){
  399           objectCache.remove(cachedObject);
  400       }
  401       
  402       
  403       /**
  404        * Return the <code>SecurityManager</code> only if Security is enabled AND
  405        * package protection mechanism is enabled.
  406        */
  407       public static boolean isPackageProtectionEnabled(){
  408           if (packageDefinitionEnabled && Globals.IS_SECURITY_ENABLED){
  409               return true;
  410           }
  411           return false;
  412       }
  413       
  414       
  415   }

Save This Page
Home » Tomcat-6.0.20 » org.apache » catalina » security » [javadoc | source]