import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.security.Permission; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; import java.security.AccessController; import java.security.Principal; import java.security.AccessControlException; import java.util.Set; import java.util.HashSet; import java.util.Locale; import javax.security.auth.Subject; public class AccessDenied { private static final String JAR_FILE = "JAR_FILE"; private static final String POLICY_FILE_CONTENTS = "grant principal " + SystemPrincipal.class.getName() + " *\n" + "{\n" + " permission " + DatabasePermission.class.getName() + " \"directory:dir\", \"create\";\n" + "};\n" + "\n" + "grant codeBase \"file://" + JAR_FILE + "\"\n" + "{\n" + " permission javax.security.auth.AuthPermission \"doAsPrivileged\";\n" + " permission java.util.PropertyPermission \"user.dir\", \"read\";\n" + "};\n"; private static final String POLICY_FILE_NAME = "accessDenied.policy"; public static void main( String... args ) throws Exception { String policyFileContents = POLICY_FILE_CONTENTS.replace ( JAR_FILE, AccessDenied.class.getProtectionDomain().getCodeSource().getLocation().getFile() ); writeFile( new File( POLICY_FILE_NAME ), policyFileContents ); System.setProperty( "java.security.policy", POLICY_FILE_NAME ); System.setSecurityManager( new SecurityManager() ); // test DatabasePermission for any user final SystemPrincipal anyUser = new SystemPrincipal("ANY_USER"); final DatabasePermission dbPerm = new DatabasePermission("directory:dir", DatabasePermission.CREATE); execute(anyUser, new CreateDatabaseAction(dbPerm)); } private static void writeFile( File file, String contents ) throws IOException { FileWriter fw = new FileWriter( file ); fw.write( contents ); fw.flush(); fw.close(); } private static void execute(SystemPrincipal principal, PrivilegedAction action) { final RunAsPrivilegedUserAction runAsPrivilegedUserAction = new RunAsPrivilegedUserAction(principal, action); try { AccessController.doPrivileged(runAsPrivilegedUserAction); } catch (AccessControlException ace) { fail("caught AccessControlException"); ace.printStackTrace(); } } private static void fail( String text ) { println( "FAIL: " + text ); } private static void println( String text ) { System.out.println( text ); } /** * Represents a Privileged User action. */ static public class RunAsPrivilegedUserAction implements PrivilegedAction { final private SystemPrincipal principal; final private PrivilegedAction action; public RunAsPrivilegedUserAction(SystemPrincipal principal, PrivilegedAction action) { this.principal = principal; this.action = action; } public Object run() { final Set principals = new HashSet(); final Set publicCredentials = new HashSet(); final Set privateCredentials = new HashSet(); principals.add(principal); principals.add(new SystemPrincipal( principal.getName() )); final Subject subject = new Subject(true, principals, publicCredentials, privateCredentials); Subject.doAsPrivileged(subject, action, null); return null; } } public static class CreateDatabaseAction implements PrivilegedAction { protected final Permission permission; public CreateDatabaseAction(Permission permission) { this.permission = permission; } public Object run() { AccessController.checkPermission(permission); return null; } public String toString() { return permission.toString(); } } static final public class DatabasePermission extends Permission { private static final long serialVersionUID = 6464298989504059473L; static public final String URL_PROTOCOL_DIRECTORY = "directory:"; static public final String CREATE = "create"; private final String url; public DatabasePermission(String url, String actions) throws IOException { super(url); this.url = url; } public boolean implies(Permission p) { return true; } public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof DatabasePermission)) { return false; } final DatabasePermission that = (DatabasePermission)obj; return url.equals(that.url); } public int hashCode() { return url.hashCode(); } public String getActions() { return CREATE; } } static final public class SystemPrincipal implements Principal, Serializable { static final long serialVersionUID = 925380094921530190L; private final String name; public SystemPrincipal(String name) { this.name = name; } public boolean equals(Object other) { if (other == null) { return false; } if (!(other instanceof SystemPrincipal)) { return false; } return name.equals(((SystemPrincipal) other).name); } public String getName() { return name; } public int hashCode() { return name.hashCode(); } public String toString() { return getClass().getName() + "(" + name + ")"; } } }