Java/Security/AccessController
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
- 1 AccessController.doPrivileged(new PrivilegedAction() )
- 2 <ClassLoader> ClassLoader java.security.AccessController.doPrivileged(PrivilegedAction<ClassLoader> action)
- 3 Load class
- 4 Lock request from going up in the classloader hierarchy
- 5 Make AccessibleObject Accessible
- 6 Search for resource in different places.
- 7 Use AccessController to check the AWT permission
- 8 Use AccessController to check the file permission
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>
* ["com.iona.", "javax.servlet.jsp."]
* </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);
}
}