每个Java应用都可以有自己的安全管理器,它是防范恶意***的主要安全卫士。安全管理器通过执行运行阶段检查和访问授权,以实施应用所需的安全策略,从 而保护资源免受恶意操作的***。实际上,安全管理器根据Java安全策略文件决定将哪组权限授予类。然而,当不可信的类和第三方应用使用JVM 时,Java安全管理器将使用与JVM相关的安全策略来识别恶意操作。在很多情况下,威胁模型不包含运行于JVM中的恶意代码,此时Java安全管理器便 不是必需的。当安全管理器检测到违反安全策略的操作时,JVM将引发AccessControlException或 SecurityException。
在Java应用中,安全管理器是由System类中的方法setSecurityManager设置的。要获得当前的安全管理器,可以使用方法getSecurityManager。
java.lang.SecurityManager类包含了很多checkXXXX方法,如用于判断对文件访问权限的checkRead(String file)方法。这些检查方法调用SecurityManager.checkPermission方法,后者根据安全策略文件判断调用应用是否有执行所 请求的操作权限。如果没有,将引发SecurityException。
如果想让应用使用安全管理器和安全策略,可在启动JVM时设定-Djava.security.manager选项,还可以同时指定安全策略文件。如果在 应用中启用了Java安全管理器,却没有指定安全策略文件,那么Java安全管理器将使用默认的安全策略,它们是由位于目录$JAVA_HOME/jre /lib/security中的java.policy定义的。
实现安全管理器步骤:
(1) 创建一个SecurityManager的子类; (2) 覆盖一些方法。 import java.io.*; public class TestSecurity { public static void main(String args[]) { try { System.setSecurityManager(new PasswordSecurityManager("123456")); } catch (SecurityException se) { System.out.println("SecurityManager already set!"); } try { //DataInputStream fis = new DataInputStream(new FileInputStream("input.txt")); BufferedReader fis = new BufferedReader(new FileReader("input.txt")); //DataOutputStream fos = new DataOutputStream( new FileOutputStream("output.txt")); BufferedWriter fos = new BufferedWriter(new FileWriter("output.txt")); String inputString; while ((inputString = fis.readLine()) != null) { //fos.writeBytes(inputString); //fos.writeByte('\n'); fos.write(inputString); fos.write('\n'); } fis.close(); fos.close(); } catch (IOException ioe) { System.out.println("I/O failed for SecurityManagerTest."); }catch(Exception e) { System.out.println(e.toString()); } } } import java.io.*; class PasswordSecurityManager extends SecurityManager { private String password; PasswordSecurityManager(String password) { super(); this.password = password; } private boolean accessOK() { int c; //DataInputStream dis = new DataInputStream(System.in); BufferedReader dis = new BufferedReader(new InputStreamReader(System.in)); String response; System.out.println("What's the secret password?"); try { response = dis.readLine(); if (response.equals(password)) return true; else return false; } catch (IOException e) { return false; } } public void checkRead(FileDescriptor filedescriptor) { if (!accessOK()) throw new SecurityException("Not a Chance!"); } public void checkRead(String filename) { if (!accessOK()) throw new SecurityException("No Way!"); } public void checkRead(String filename, Object executionContext) { if (!accessOK()) throw new SecurityException("Forget It!"); } public void checkWrite(FileDescriptor filedescriptor) { if (!accessOK()) throw new SecurityException("Not!"); } public void checkWrite(String filename) { if (!accessOK()) throw new SecurityException("Not Even!"); } }