一、JavaDoc如是说
安全管理器是一个允许应用程序实现安全策略的类。它允许应用程序在执行一个可能不安全或敏感的操作前确定该操作是什么,以及是否是在允许执行该操作的安全上下文中执行它。应用程序可以允许或不允许该操作。
SecurityManager 类包含了很多名称以单词 check 开头的方法。Java 库中的各种方法在执行某些潜在的敏感操作前可以调用这些方法。对 check 方法的典型调用如下:
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkXXX(argument, . . . );
}
因此,安全管理器通过抛出异常来提供阻止操作完成的机会。如果允许执行该操作,则安全管理器例程只是简单地返回,但如果不允许执行该操作,则抛出一个 SecurityException。该约定的唯一例外是 checkTopLevelWindow,它返回 boolean 值。
当前的安全管理器由 System 类中的 setSecurityManager 方法设置。当前的安全管理器由 getSecurityManager 方法获得。
特殊方法 checkPermission(java.security.Permission)确定是应该允许还是拒绝由指定权限所指示的访问请求。默认的实现调用
AccessController.checkPermission(perm);
如果允许访问请求,则安静地返回 checkPermission。如果拒绝访问请求,则抛出 SecurityException。
从 Java 2 SDK v1.2 开始,SecurityManager 中其他所有 check 方法的默认实现都是调用 SecurityManager checkPermission 方法来确定调用线程是否具有执行所请求操作的权限。
注意,只带有单个权限参数的 checkPermission 方法总是在当前执行的线程上下文中执行安全检查。有时,应该在给定上下文中进行的安全检查实际上需要在不同 的上下文(例如,在一个辅助线程中)中进行。Java 为这种情况提供了包含有上下文参数的 getSecurityContext方法和 checkPermission方法。getSecurityContext 方法返回当前调用上下文的一个“快照”(默认的实现返回一个 AccessControlContext 对象)。下面是一个示例调用:
Object context = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) context = sm.getSecurityContext();
checkPermission 方法使用一个上下文对象,以及根据该上下文而不是当前执行线程的上下文作出访问决策的权限。因此另一个上下文中的代码可以调用此方法,传递权限和以前保存的上下文对象。下面是一个示例调用,它使用了以前示例中获得的 SecurityManager sm:
if (sm != null) sm.checkPermission(permission, context);
权限分为以下类别:文件、套接字、网络、安全性、运行时、属性、AWT、反射和可序列化。管理各种权限类别的类是 java.io.FilePermission、java.net.SocketPermission、java.net.NetPermission、java.security.SecurityPermission、java.lang.RuntimePermission、java.util.PropertyPermission、java.awt.AWTPermission、java.lang.reflect.ReflectPermission 和 java.io.SerializablePermission。
除前两个(FilePermission 和 SocketPermission)类以外的所有类都是 java.security.BasicPermission 的子类,而 java.security.BasicPermission 类又是顶级权限类 java.security.Permission 的抽象子类。BasicPermission 定义了所有权限所需的功能,这些功能的名称遵从分层属性命名惯例(例如“exitVM”、“setFactory”、“queuePrintJob”等等)。在名称的末尾可能出现一个星号,前面是“.”或星号,这表示通配符匹配。例如:“a.*”、“*”是有效的,而“*a”或“a*b”是无效的。
FilePermission 和 SocketPermission 是顶级权限类 (java.security.Permission) 的子类。像这些命名语法比 BasicPermission 所用的语法更为复杂的类都直接是 Permission 的子类,而不是 BasicPermission 的子类。例如,对于 java.io.FilePermission 对象而言,权限名就是文件(或目录)的路径名。
某些权限类具有一个“动作”列表,告知允许对象所执行的动作。例如,对于 java.io.FilePermission 对象,动作列表(如“读、写”)指定了允许对指定文件(或指定目录中的文件)执行哪些动作。
其他权限类是“指定的”权限 - 有名称但没有动作列表的类;您也许有指定的权限,也许没有。
注:还有一个暗指所有权限的 java.security.AllPermission 权限。该权限是为了简化系统管理员的工作而存在的,因为管理员可能需要执行很多需要所有(或许多)权限的任务。
二、启动/关闭SecurityManager
1. 指定 -Djava.security.manager
当我们运行一个程序,我们可以指定JVM命令 -Djava.security.manager 使SecurityManager运行。
java -Djava.security.manager <class_name> |
这是打开SecurityManager最常见的方式。java.security.manager是一个系统属性,您可以使用System.getProperty(“java.security.manager”)检查该系统属性是否被设置。
在这里,你可能会认为,我们可以使用System.setProperty(“java.security.manager”)打开SecurityManager,但是并不能这么设置。因为先前我们提到,这个系统属性是在当JVM启动时进行检查的。如果我们用程序手动设置该属性,并不能奏效,因为JVM已经启动了,已经过了检查系统属性的步骤了。
2. 通过程序打开SecurityManager
现在,如果我们真的想通过我们的程序打开SecurityManager,我们也能做到。 System类中有一个叫 setSecurityManager() 的方法可以做到这一点。这个方法的参数是一个SecurityManager实例。
SecurityManager sm=new SecurityManager(); System.setSecurityManager(sm); |
通过这个,我们可以打开SecurityManager.。如果之后我们想要关闭SecurityManager, 我们该怎么做? 下面的代码能做到吗?
SecurityManager sm=System.getSecurityManager(); if(sm!=null){ System.setSecurityManager(null); } |
上面的代码只有你在位于${JDK_HOME}/jre/lib/security目录下或者其他指定目录下的java.policy文件中指定了一个权限才会奏效。 这个权限是:
permission java.lang.RuntimePermission "setSecurityManager"; |
上面的一行将被用来允许代码设置SecurityManager
三、Java policy文件
默认加载的策略文件的位置,我们可以从${JDK_HOME}/jre/lib/security目录下的java.security文件中看到:
# The default is to have a single system-wide policy file, # and a policy file in the user's home directory. policy.url.1=file:${java.home}/lib/security/java.policy policy.url.2=file:${user.home}/.java.policy |
|
也可以在启动的时候指定其他位置的策略文件:
java -Djava.security.manager -Djava.security.policy=someURL SomeApp
四、权限分类
JDK8有下面这么多的权限类,每个权限类控制某一方面的相关权限,而每个权限类可能又会有不同的动作,所以控制范围是方方面面的。
五、自定义SecurityManager
public class SecurityManagerTest { private static class MySecurityManager extends SecurityManager { @Override public void checkRead(String file) { if ("java.policy".contains(file)) { throw new AccessControlException("cannot read file:" + file); } super.checkRead(file); } } public static void main(String[] args) throws FileNotFoundException { //install System.setSecurityManager(new MySecurityManager()); //read InputStream in = new FileInputStream(new File("java.policy")); //uninstall SecurityManager sm = System.getSecurityManager(); if (sm != null) { System.setSecurityManager(null); } } }
输出:
Exception in thread "main" java.security.AccessControlException: cannot read file:java.policy at grucee.test.SecurityManagerTest$MySecurityManager.checkRead(SecurityManagerTest.java:17) at java.io.FileInputStream.<init>(FileInputStream.java:121) at grucee.test.SecurityManagerTest.main(SecurityManagerTest.java:29)
|
六、SecurityManager在tomcat中的使用(翻译)
1.背景
Java SecurityManager可以让web浏览器在它自己的沙箱中运行applet,从而防止不可信代码访问本地文件系统中的文件、连接applet加载主机之外的主机,等等。同样,SecurityManager可以阻止你的浏览器运行不安全的applet;运行tomcat的时候,使用SecurityManager可以保护你的机器不受恶意Servlet、JSP,甚至是疏忽的错误的影响。
想象一下一个有权限发布JSP页面的人员,由于输出在他们的JSP页面中包括了下面这句:
<% System.exit(1); %>
Tomcat每次执行这个JSP,tomcat都会退出。使用Java SecurityManager是系统管理员保证服务器安全、可靠地另外一种防线。
无论如何,运行SecurityManger比不运行要好很多。
2.Permissions
Permission类用来定义tomcat加载的类应该有什么权限。JDK有很多标准的Permission类,并且你可以创建自己的Permission类。Tomcat两种技术都有使用。
标准Permissions
这里只是适用于tomcat的标准SecurityManager Permission类的总结:
|
Tomcat自定义Permissions
Tomcat使用了 org.apache.naming.JndiPermission的自定义权限类。该权限控制基于JNDI命名的资源的访问。权限的名称是JNDI名,无动作。可以使用结尾的*来进行模糊匹配,例如
permission org.apache.naming.JndiPermission "jndi://localhost/examples/*";
每个部署的Web应用都会动态生成这样的权限实体,以允许读取自己的静态资源,而不允许读取其他的文件(除非显示赋予这些文件的权限)。
而且,Tocat总是动态创建下面的文件权限:
permission java.io.FilePermission "** your application context**", "read";
permission java.io.FilePermission
"** application working directory**", "read,write";
permission java.io.FilePermission
"** application working directory**/-", "read,write,delete";
这里的**your application context”等同于应用程序部署的目录(或WAR文件),**application working directory**是Servlet规范要求的临时目录。
3.使用SecurityManager配置Tomcat
策略文件格式
Java SecurityManager实现的安全策略文件配置在$CATALINA_BASE/conf/catalina.policy。该文件完全替换JDK目录中的java.policy文件。catalina.policy文件可以手动编辑,也可以使用Java 1.2及以上自带的policytool工具。
catalina.policy文件中的实体使用标准java.policy文件的格式,如下:
// Example policy file entry
grant [signedBy <signer>,] [codeBase <code source>] {
permission <class> [<name> [, <action list>]];
};
signedBy和codeBase实体在赋予权限的时候是可选的。注释以//开头并至行尾。codeBase以URL的格式,文件URL可以使用${java.home}和${catalina.home} 属性(将来会扩展到JAVA_HOME,CATALINA_HOME以及CATALINA_BASE环境变量)。
4.使用SecurityManager启动Tomcat
$CATALINA_HOME/bin/catalina.sh start -security (Unix)
%CATALINA_HOME%\bin\catalina start -security (Windows)
一旦你配置了catalina.policy文件,Tomcat可以使用”-security”选项启动SecurityManager。
相关推荐
创建安全管理器利用安全管理器public static void main(String args[]){方法调用此方法时,返回所有新创建的线程实例化后所在的线
3.10.1 使用安全管理器的实例 51 3.10.2 JDK1.2中没有改变的API 52 3.10.3 JDK1.2中禁用的方法 53 3.11 java.security.AccessController 56 3.11.1 AceessController的界面设计 57 3.11.2 基础访问控制算法 57 ...
3.10.1 使用安全管理器的实例 51 3.10.2 JDK1.2中没有改变的API 52 3.10.3 JDK1.2中禁用的方法 53 3.11 java.security.AccessController 56 3.11.1 AceessController的界面设计 57 3.11.2 基础访问控制算法 57 ...
在现代的Java Web应用开发中,使用SSM(Spring + Spring MVC + MyBatis)框架组合是一种非常流行的做法。...在权限控制方面,可以配置Shiro的安全管理器(SecurityManager)和授权信息(如角色和权限)。
Java Shiro 是一个强大且灵活的开源安全框架,用于身份认证、授权和会话管理等安全领域的应用开发。学习 Java Shiro 可以通过思维导图来梳理核心概念和学习路径,以下是一个简要的 Java Shiro 学习思维导图。 Java ...
安全经理Java安全管理器的定制实现,旨在为Web应用程序提供额外的保护和保证。 它允许使用更灵活的许可算法,以更好地满足J2EE环境的安全需求。背景默认的Java安全管理器实现被设计为用于不受信任的代码的通用沙箱。...
SecurityManager : 安全管理器(关联 Realm) Realm :Shiro 连接数据的桥梁 【备注】 主要针对计算机相关专业的正在做毕设的学生和需要项目实战的Java学习者。 也可作为课程设计、期末大作业。包含:项目源码、...
Java 对通过网络下载的类具有一个安全防范机制(类 ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类 SecurityManager)让 Java 应用设置安全哨兵。 Java 语言是可...
安全管理器 SecurityManager; 过滤器工厂 ShiroFilterFactoryBean(设置自定义过滤器和设置哪些路径是允许匿名访问); 自定义realm(数据源,从数据库获得真实用户信息(密码权限),并封装成...
java对通过网络下载的类具 有一个安全防范机制(类classloader),如分配不同的名字空间以防替代本地的同名类 、字节代码检查,并提供安全管理机制(类securitymanager)让java应用设置安全哨兵 。多元性,作为现下...
ApacheShiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。对于任何一个应用程序,Shiro都可以提供全面的安全管理服务。其不仅可以用在JavaSE环境,也可以用在JavaEE环境。1.从外部来看...
Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能: 认证 – 用户身份识别,常被称为用户“登录”; 授权 – 访问控制; 密码加密 – 保护或隐藏数据防止被偷窥; ...
Apache Shiro(发音为“shee-roh”,日语“堡垒(Castle)”的意思)是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可为任何应用提供安全保障 – 从命令行应用、移动应用到大型网络及企业...
SecurityManager : 安全管理器(关联 Realm) Realm :Shiro 连接数据的桥梁 数据库表 shiro 引入 <groupId>org.apache.shiro <artifactId>shiro-spring <version>1.4.0 简单拦截 public ...
SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。 配置applicationContext-shiro.xml 1. 配置authorizingRealm 2.Shiro Filter 设置拦截的内容和登录页面和...