Save This Page
Home » apache-tomcat-6.0.16-src » 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           Method method = null;
  200   
  201           Method[] methodsCache = null;
  202           if(objectCache.containsKey(targetObject)){
  203               methodsCache = (Method[])objectCache.get(targetObject);
  204               method = findMethod(methodsCache, methodName);
  205               if (method == null){
  206                   method = createMethodAndCacheIt(methodsCache,
  207                                                   methodName,
  208                                                   targetObject,
  209                                                   targetType);
  210               }
  211           } else {
  212               method = createMethodAndCacheIt(methodsCache,
  213                                               methodName,
  214                                               targetObject,
  215                                               targetType);                     
  216           }
  217   
  218           execute(method, targetObject, targetArguments, null);
  219       }
  220       
  221       
  222       /**
  223        * Perform work as a particular </code>Subject</code>. Here the work
  224        * will be granted to a <code>null</code> subject. 
  225        *
  226        * @param methodName the method to apply the security restriction
  227        * @param targetObject the <code>Servlet</code> on which the method will
  228        * be called.
  229        * @param targetArguments <code>Object</code> array contains the 
  230        * runtime parameters instance.
  231        * @param principal the <code>Principal</code> to which the security 
  232        * privilege applies
  233        */    
  234       private static void execute(final Method method,
  235                                   final Object targetObject, 
  236                                   final Object[] targetArguments,
  237                                   Principal principal) 
  238           throws java.lang.Exception{
  239          
  240           try{   
  241               Subject subject = null;
  242               PrivilegedExceptionAction pea = new PrivilegedExceptionAction(){
  243                       public Object run() throws Exception{
  244                          method.invoke(targetObject, targetArguments);
  245                          return null;
  246                       }
  247               };
  248   
  249               // The first argument is always the request object
  250               if (targetArguments != null 
  251                       && targetArguments[0] instanceof HttpServletRequest){
  252                   HttpServletRequest request = 
  253                       (HttpServletRequest)targetArguments[0];
  254   
  255                   boolean hasSubject = false;
  256                   HttpSession session = request.getSession(false);
  257                   if (session != null){
  258                       subject = 
  259                           (Subject)session.getAttribute(Globals.SUBJECT_ATTR);
  260                       hasSubject = (subject != null);
  261                   }
  262   
  263                   if (subject == null){
  264                       subject = new Subject();
  265                       
  266                       if (principal != null){
  267                           subject.getPrincipals().add(principal);
  268                       }
  269                   }
  270   
  271                   if (session != null && !hasSubject) {
  272                       session.setAttribute(Globals.SUBJECT_ATTR, subject);
  273                   }
  274               }
  275   
  276               Subject.doAsPrivileged(subject, pea, null);       
  277          } catch( PrivilegedActionException pe) {
  278               Throwable e = ((InvocationTargetException)pe.getException())
  279                                   .getTargetException();
  280               
  281               if (log.isDebugEnabled()){
  282                   log.debug(sm.getString("SecurityUtil.doAsPrivilege"), e); 
  283               }
  284               
  285               if (e instanceof UnavailableException)
  286                   throw (UnavailableException) e;
  287               else if (e instanceof ServletException)
  288                   throw (ServletException) e;
  289               else if (e instanceof IOException)
  290                   throw (IOException) e;
  291               else if (e instanceof RuntimeException)
  292                   throw (RuntimeException) e;
  293               else
  294                   throw new ServletException(e.getMessage(), e);
  295           }  
  296       }
  297       
  298       
  299       /**
  300        * Find a method stored within the cache.
  301        * @param methodsCache the cache used to store method instance
  302        * @param methodName the method to apply the security restriction
  303        * @return the method instance, null if not yet created.
  304        */
  305       private static Method findMethod(Method[] methodsCache,
  306                                        String methodName){
  307           if (methodName.equalsIgnoreCase(INIT_METHOD) 
  308                   && methodsCache[INIT] != null){
  309               return methodsCache[INIT];
  310           } else if (methodName.equalsIgnoreCase(DESTROY_METHOD) 
  311                   && methodsCache[DESTROY] != null){
  312               return methodsCache[DESTROY];            
  313           } else if (methodName.equalsIgnoreCase(SERVICE_METHOD) 
  314                   && methodsCache[SERVICE] != null){
  315               return methodsCache[SERVICE];
  316           } else if (methodName.equalsIgnoreCase(DOFILTER_METHOD) 
  317                   && methodsCache[DOFILTER] != null){
  318               return methodsCache[DOFILTER];          
  319           } 
  320           return null;
  321       }
  322       
  323       
  324       /**
  325        * Create the method and cache it for further re-use.
  326        * @param methodsCache the cache used to store method instance
  327        * @param methodName the method to apply the security restriction
  328        * @param targetObject the <code>Servlet</code> on which the method will
  329        * be called.
  330        * @param targetType <code>Class</code> array used to instanciate a 
  331        * <code>Method</code> object.
  332        * @return the method instance.
  333        */
  334       private static Method createMethodAndCacheIt(Method[] methodsCache,
  335                                                    String methodName,
  336                                                    Object targetObject,
  337                                                    Class[] targetType) 
  338               throws Exception{
  339           
  340           if ( methodsCache == null){
  341               methodsCache = new Method[3];
  342           }               
  343                   
  344           Method method = 
  345               targetObject.getClass().getMethod(methodName, targetType); 
  346   
  347           if (methodName.equalsIgnoreCase(INIT_METHOD)){
  348               methodsCache[INIT] = method;
  349           } else if (methodName.equalsIgnoreCase(DESTROY_METHOD)){
  350               methodsCache[DESTROY] = method;
  351           } else if (methodName.equalsIgnoreCase(SERVICE_METHOD)){
  352               methodsCache[SERVICE] = method;
  353           } else if (methodName.equalsIgnoreCase(DOFILTER_METHOD)){
  354               methodsCache[DOFILTER] = method;
  355           } 
  356            
  357           objectCache.put(targetObject, methodsCache );
  358                                              
  359           return method;
  360       }
  361   
  362       
  363       /**
  364        * Remove the object from the cache.
  365        *
  366        * @param cachedObject The object to remove
  367        */
  368       public static void remove(Object cachedObject){
  369           objectCache.remove(cachedObject);
  370       }
  371       
  372       
  373       /**
  374        * Return the <code>SecurityManager</code> only if Security is enabled AND
  375        * package protection mechanism is enabled.
  376        */
  377       public static boolean isPackageProtectionEnabled(){
  378           if (packageDefinitionEnabled && Globals.IS_SECURITY_ENABLED){
  379               return true;
  380           }
  381           return false;
  382       }
  383       
  384       
  385   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » security » [javadoc | source]