Java/Security/AccessController

Материал из Java эксперт
Перейти к: навигация, поиск

AccessController.doPrivileged(new PrivilegedAction() )

 
import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class Main {
  
  static long getLastModified(final File f) {
      return ((Long)
              AccessController.doPrivileged(new PrivilegedAction() {
                  public Object run() {
                      return new Long(f.lastModified());
                  }
              })).longValue();
  }
  
}





<ClassLoader> ClassLoader java.security.AccessController.doPrivileged(PrivilegedAction<ClassLoader> action)

 
/*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, JBoss Inc., and individual contributors as indicated
  * by the @authors tag. See the copyright.txt in the distribution for a
  * full listing of individual contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
import java.security.AccessController;
import java.security.PrivilegedAction;
/** A collection of privileged actions
 * @author Clebert Suconic
 */
class SecurityActions
{
   static ClassLoader getTCL()
   {
      if (System.getSecurityManager() == null)
      {
         return Thread.currentThread().getContextClassLoader();
      }
      else
      {
         return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
         {
            public ClassLoader run()
            {
               return Thread.currentThread().getContextClassLoader();
            }
         });
      }
   }
   static ClassLoader getClassLoader(final Class<?> clazz)
   {
      if (System.getSecurityManager() == null)
      {
         return clazz.getClassLoader();
      }
      else
      {
         return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
         {
            public ClassLoader run()
            {
               return clazz.getClassLoader();
            }
         });
      }
   }
   static void setTCL(final ClassLoader tcl)
   {
      if (System.getSecurityManager() == null)
      {
         Thread.currentThread().setContextClassLoader(tcl);
      }
      else
      {
         AccessController.doPrivileged(new PrivilegedAction<Object>()
         {
            public Object run()
            {
               Thread.currentThread().setContextClassLoader(tcl);
               return null;
            }
         });
      }
   }
}





Load class

 
/*
 * Copyright  2003-2008 The Apache Software Foundation.
 *
 *  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.
 *
 */
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
public class Main {
  /**
   * If running under JDK 1.2 load the specified class using the
   * <code>Thread</code> <code>contextClassLoader</code> if that
   * fails try Class.forname.
   * <p/>
   *
   * @param clazz
   * @return TODO
   * @throws ClassNotFoundException
   */
  public static Class loadClass(String clazz) throws ClassNotFoundException {
      return loadClass(clazz, true);
  }
  
  public static Class loadClass(String clazz, boolean warn) throws ClassNotFoundException {
      try {
          ClassLoader tcl = getTCL(); 
          
          if (tcl != null) {
              Class c = tcl.loadClass(clazz);
              if (c != null) {
                  return c;
              }
          }
      } catch (Throwable e) {
      }
      // we reached here because tcl was null or because of a
      // security exception, or because clazz could not be loaded...
      // In any case we now try one more time
      return Class.forName(clazz);
  }
  /**
   * Get the Thread context class loader.
   * <p/>
   *
   * @return the Thread context class loader
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static ClassLoader getTCL() throws IllegalAccessException, InvocationTargetException {
       return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
          public Object run() {
              return Thread.currentThread().getContextClassLoader();
          }
       });
  }
}





Lock request from going up in the classloader hierarchy

 
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */
import java.security.SecureClassLoader;
/**
 * The FireWallClassLoader is a classloader that can block request from going up
 * in the classloader hierarchy.
 * <P>
 * Normally, when a classloader receives a request for a resource, it will
 * consult its parent class loader first for that resource. The parent class
 * loader is typically the System ClassLoader. If the parent class loader cannot
 * provide the requested resource, the child class loader will be consulted for
 * the request. <I>Note: the parent class loader must not be confused by the
 * superclass of a certain class loader (e.g. SecureClassLoader). The parent
 * classloader is identified at constuction time and passed in as an constructor
 * argument.</I>
 * <P>
 * Consulting the parent classloader first can be inconvenient for certain
 * applications that want guarantees about which classloader is used to load a
 * certain class. This could be because you want to be certain about where the
 * resource came from, or you want to protect yourself against (other versions)
 * of the same class that could be served by the System ClassLoader (e.g.
 * because someone put them on the classpath or in the extensions directory).
 * <P>
 * For these cases, the FireWallClassLoader can be used.
 * 
 * <PRE>
 * 
 * System ClassLoader | FireWallClassLoader | User"s ClassLoader
 * 
 * </PRE>
 * 
 * The FireWallClassLoader is placed between the user"s class loader and the
 * parent class loader. It has a set of filters that define what classes are
 * allowed to go through. These filters describe (a groups of) packages, or a
 * specific classes or resources that are allowed through to the parent
 * classloader. Take as example this filter set:
 * 
 * <pre>
 * [&quot;com.iona.&quot;, &quot;javax.servlet.jsp.&quot;]
 * </pre>
 * 
 * This will allow requests to any class/resource staring with com.iona. or
 * javax.servlet.jsp. through to the parent classloader and block all other
 * requests.
 * <P>
 * A very common set of filters would be a set that allows nothing through
 * except the classes used by the JDK. The {@link JDKFireWallClassLoaderFactory}
 * factory class can create such FireWallClassLoader.
 * <P>
 * The FireWallClassLoader does not load any classes.
 */
public class FireWallClassLoader extends SecureClassLoader {
    private final String[] filters;
    private final String[] fnFilters;
    private final String[] negativeFilters;
    private final String[] negativeFNFilters;
    /**
     * Constructor.
     * 
     * @param parent The Parent ClassLoader to use.
     * @param fs A set of filters to let through. The filters and be either in
     *            package form (<CODE>org.omg.</CODE> or <CODE>org.omg.*</CODE>)
     *            or specify a single class (<CODE>junit.framework.TestCase</CODE>).
     *            <P>
     *            When the package form is used, all classed in all subpackages
     *            of this package are let trough the firewall. When the class
     *            form is used, the filter only lets that single class through.
     *            Note that when that class depends on another class, this class
     *            does not need to be mentioned as a filter, because if the
     *            originating class is loaded by the parent classloader, the
     *            FireWallClassLoader will not receive requests for the
     *            dependant class.
     */
    public FireWallClassLoader(ClassLoader parent, String[] fs) {
        this(parent, fs, new String[0]);
    }
    /**
     * Constructor.
     * 
     * @param parent The Parent ClassLoader to use.
     * @param fs A set of filters to let through. The filters and be either in
     *            package form (<CODE>org.omg.</CODE> or <CODE>org.omg.*</CODE>)
     *            or specify a single class (<CODE>junit.framework.TestCase</CODE>).
     *            <P>
     *            When the package form is used, all classed in all subpackages
     *            of this package are let trough the firewall. When the class
     *            form is used, the filter only lets that single class through.
     *            Note that when that class depends on another class, this class
     *            does not need to be mentioned as a filter, because if the
     *            originating class is loaded by the parent classloader, the
     *            FireWallClassLoader will not receive requests for the
     *            dependant class.
     * @param negativeFs List of negative filters to use. Negative filters take
     *            precedence over positive filters. When a class or resource is
     *            requested that matches a negative filter it is not let through
     *            the firewall even if an allowing filter would exist in the
     *            positive filter list.
     */
    public FireWallClassLoader(ClassLoader parent, String[] fs, String[] negativeFs) {
        super(parent);
        this.filters = processFilters(fs);
        this.negativeFilters = processFilters(negativeFs);
        this.fnFilters = filters2FNFilters(this.filters);
        this.negativeFNFilters = filters2FNFilters(this.negativeFilters);
        boolean javaCovered = false;
        if (this.filters == null) {
            javaCovered = true;
        } else {
            for (int i = 0; i < this.filters.length; i++) {
                if (this.filters[i].equals("java.")) {
                    javaCovered = true;
                }
            }
        }
        if (this.negativeFilters != null) {
            String java = "java.";
            // try all that would match java: j, ja, jav, java and java.
            for (int i = java.length(); i >= 0; i--) {
                for (int j = 0; j < this.negativeFilters.length; j++) {
                    if (negativeFilters[j].equals(java.substring(0, i))) {
                        javaCovered = false;
                    }
                }
            }
        }
        if (!javaCovered) {
            throw new SecurityException("It"s unsafe to construct a " 
                        + "FireWallClassLoader that does not let the java. " 
                        + "package through.");
        }
    }
    private static String[] processFilters(String[] fs) {
        if (fs == null || fs.length == 0) {
            return null;
        }
        String[] f = new String[fs.length];
        for (int i = 0; i < fs.length; i++) {
            String filter = fs[i];
            if (filter.endsWith("*")) {
                filter = filter.substring(0, filter.length() - 1);
            }
            f[i] = filter;
        }
        return f;
    }
    private static String[] filters2FNFilters(String[] fs) {
        if (fs == null || fs.length == 0) {
            return null;
        }
        String[] f = new String[fs.length];
        for (int i = 0; i < fs.length; i++) {
            f[i] = fs[i].replace(".", "/");
        }
        return f;
    }
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        if (negativeFilters != null) {
            for (int i = 0; i < negativeFilters.length; i++) {
                if (name.startsWith(negativeFilters[i])) {
                    throw new ClassNotFoundException(name);
                }
            }
        }
        if (filters != null) {
            for (int i = 0; i < filters.length; i++) {
                if (name.startsWith(filters[i])) {
                    return super.loadClass(name, resolve);
                }
            }
        } else {
            return super.loadClass(name, resolve);
        }
        throw new ClassNotFoundException(name);
    }
    /*protected Class<?> findClass(String name) throws ClassNotFoundException {
        if (negativeFilters != null) {
            for (int i = 0; i < negativeFilters.length; i++) {
                if (name.startsWith(negativeFilters[i])) {
                    throw new ClassNotFoundException(name);
                }
            }
        }
        if (filters != null) {
            for (int i = 0; i < filters.length; i++) {
                if (name.startsWith(filters[i])) {
                    return super.findClass(name);
                }
            }
        } else {
            return super.loadClass(name);
        }
        throw new ClassNotFoundException(name);
    }*/
    
    public java.net.URL getResource(String name) {
        if (negativeFNFilters != null) {
            for (int i = 0; i < negativeFNFilters.length; i++) {
                if (name.startsWith(negativeFNFilters[i])) {
                    return null;
                }
            }
        }
        if (fnFilters != null) {
            for (int i = 0; i < fnFilters.length; i++) {
                if (name.startsWith(fnFilters[i])) {
                    return super.getResource(name);
                }
            }
        } else {
            return super.getResource(name);
        }
        return null;
    }
    /**
     * Returns the list of filters used by this FireWallClassLoader. The list is
     * a copy of the array internally used.
     * 
     * @return The filters used.
     */
    public String[] getFilters() {
        if (filters == null) {
            return null;
        }
        return (String[])filters.clone();
    }
    /**
     * Returns the list of negative filters used by this FireWallClassLoader.
     * The list is a copy of the array internally used.
     * 
     * @return The filters used.
     */
    public String[] getNegativeFilters() {
        if (negativeFilters == null) {
            return null;
        }
        return (String[])negativeFilters.clone();
    }
}





Make AccessibleObject Accessible

 
import java.lang.reflect.AccessibleObject;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class Utils {

  public static void makeAccessible( final AccessibleObject object ) {
      if (!object.isAccessible()) {
          if (System.getSecurityManager() == null) {
              object.setAccessible(true);
          } else {
              AccessController.doPrivileged(new PrivilegedAction<Object>() {
                  public Object run() {
                      object.setAccessible(true);
                      return null;
                  }
              });
          }
      }
  }
}





Search for resource in different places.

 
/*
 * Copyright  2003-2008 The Apache Software Foundation.
 *
 *  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.
 *
 */
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
public class Main {
  /**
   * This method will search for <code>resource</code> in different
   * places. The search order is as follows:
   * <ol>
   * <p><li>Search for <code>resource</code> using the thread context
   * class loader under Java2.
   * <p><li>Try one last time with
   * <code>ClassLoader.getSystemResource(resource)</code>, that is is
   * using the system class loader in JDK 1.2 and virtual machine"s
   * built-in class loader in JDK 1.1.
   * </ol>
   * <p/>
   *
   * @param resource
   * @return TODO
   */
  public static URL getResource(String resource) {
      ClassLoader classLoader = null;
      URL url = null;
      try {
          classLoader = getTCL();
          if (classLoader != null) {
              url = classLoader.getResource(resource);
              if (url != null) {
                  return url;
              }
          }
      } catch (Throwable t) {
      }
  
      // Last ditch attempt: get the resource from the class path. It
      // may be the case that clazz was loaded by the Extension class
      // loader which the parent of the system class loader. Hence the
      // code below.
   
      return ClassLoader.getSystemResource(resource);
  }
  /**
   * Get the Thread context class loader.
   * <p/>
   *
   * @return the Thread context class loader
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static ClassLoader getTCL() throws IllegalAccessException, InvocationTargetException {
       return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
          public Object run() {
              return Thread.currentThread().getContextClassLoader();
          }
       });
  }
}





Use AccessController to check the AWT permission

  
import java.awt.AWTPermission;
import java.io.FilePermission;
import java.security.AccessController;
public class MainClass {
  public static void main(String args[]) throws Exception {
    AWTPermission ap = new AWTPermission("accessClipboard");
    AccessController.checkPermission(ap);
  }
}





Use AccessController to check the file permission

  
import java.awt.AWTPermission;
import java.io.FilePermission;
import java.security.AccessController;
public class MainClass {
  public static void main(String args[]) throws Exception {
    FilePermission fp = new FilePermission("c:\\autoexec.bat", "read");
    AccessController.checkPermission(fp);
  }
}