# 前言
简单了解 SecurityManager。具体查阅 API。
# What
它是 Java 沙盒模型控制安全的重要一个环节。它是 Java 的一个类。下面一段话源于SecurityManager API:
The security manager is a class that allows applications to implement a security policy. It allows an application to determine, before performing a possibly unsafe or sensitive operation, what the operation is and whether it is being attempted in a security context that allows the operation to be performed. The application can allow or disallow the operation.
安全管理器是一个类,允许应用实现一个安全策略。在执行一项可能不安全或者敏感操作之前,它允许应用去确定这个操作的内容以及这个操作是否允许去修改安全上下文。这个应用可也允许或者阻止该行为。
简单的说,他规定了权限,类访问权限,文件访问权限等等,范围很广,你能想到的,它都有。只要在命令行运行时附加参数,或者在程序运行前设置该类即可。
# Why
至于使用这个类作为安全机制的原因:Java 原生安全机制,对于简单应用,为什么不用?
至于使用场合,比如恶意的反射:
假设有个安全控制类:
public class Security {boolean security = true;
// 我是 private 方法,我不想被外人访问!private void changeSecurity() {security = false;}public boolean getSecurity() {return security;}}
然后黑客想要修改安全:
import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Random;public class Main {public static void main(String[] args) { Class securityClass = Security.class;try {Security security = (Security) securityClass.newInstance();Method method = securityClass.getDeclaredMethod("changeSecurity");method.setAccessible(true); // 让我访问 private 方法System.out.println("Security level: " + security.getSecurity());method.invoke(security);System.out.println("Security level: " + security.getSecurity());} catch (Exception e) {e.printStackTrace();}}}
这是很邪恶的,一下子就把安全选项给关闭了。
# How
然而阻止黑客这么做很简单,附加 SecurityManager 禁用反射即可:
import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Random;public class Main {public static void main(String[] args) {System.setSecurityManager(new SecurityManager()); // 设置了 SecurityManagerClass securityClass = Security.class;try {Security security = (Security) securityClass.newInstance();Method method = securityClass.getDeclaredMethod("changeSecurity");method.setAccessible(true);System.out.println("Security level: " + security.getSecurity());method.invoke(security);System.out.println("Security level: " + security.getSecurity());} catch (Exception e) {e.printStackTrace();}} }
# Reference
http://docs.oracle.com/javase/8/docs/api/java/lang/SecurityManager.html SecurityManager API