Java安全管理器(Security Manager)

每个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定义的。 
概念 
策略(Policy) 
    类装载器用Policy对象帮助它们决定,把一段代码导入虚拟机时应该给它们什么样的权限. 任何时候,每一个应用程序都只有一个Policy对象. 
策略文件 
    Sun的java1.2平台具体的Policy子类采用在一ASCII策略文件中用上下文无关文法描述安全策略. 
    一个策略文件包括了一系列grant子句,每一个grant子句将一些权限授给一个代码来源。 
保护域(ProtectionDomain) 
    当类装载器将类型装入 java虚拟机时,它们将为每一个类型指派一个保护域,保护域定义了授予 
   一段特定的代码的所有权限.装载入java虚拟机的每一个类型都属于一个且仅属于一个保护域. 
访问控制器(AccessController) 
     implies() 
          判断一个Permissioin对象的权限,是否隐含(imply)在另一个Permissioin对象的权限中。 
    checkPermission() 
         AccessController的核心方法,这个方法决定一个特定的操作能否被允许. 
         它自顶向下检查栈,只要它遇到一个没有权限桢,它将抛出一个AccessControlException导常。 
    doPrivileged() 
         有的时候,调用栈较上层(更靠近栈顶)的代码可能希望执行一段代码,而这段代码在调用栈的较 
         下层是不允许执行的。 
          为了使可信的代码执行较不可靠的代码操作(这段不可靠的代码位于调用栈的较下层且没有执行 
          这个操作的权限),AccessController类重载了四个名为doPrivileged()的静态方法. 
          AccessController 会忽略调用doPrivileged()方法的调用者的调用者的权限. 
    Permission: 
          权限是用抽象类java.security.Permission的一个子类的实例表示的. 
    CodeSource: 
         代码来源,包含代码库URL和签名者. 
    Permissions: 
        PermissionCollection(权限集合)的子类 
        
装载时生成保护域的步骤: 
1           根据指定的Policy文件生成一个Policy对象 
2           生成CodeSource 
3           用CodeSource在Policy中找到CodeSource对应的Permissions 
4           用CodeSource和Permissons构造一个ProtectionDomain 
5           把ProtectionDomain同这个类在方法区中的类数据联系起来(ClassLoader.defineClass()). 


运行权限检查: 
如当前应用程序执行new FileInputStream(“a.txt”),java会检查当前代码有没有读”a.txt”的权限. 
步骤: 
1           调用SecurityManager.checkRead()方法 
2           调用AccessControl.checkPermission()方法,执行栈检查 

实现安全管理器步骤: 

(1) 创建一个SecurityManager的子类; 
(2) 覆盖一些方法。 
Java代码   收藏代码
  1. import java.io.*;  
  2.   
  3. public class TestSecurity  
  4. {  
  5.    public static void main(String args[])  
  6.    {  
  7.         try {  
  8.                System.setSecurityManager(new PasswordSecurityManager("123456"));  
  9.             } catch (SecurityException se) {  
  10.                 System.out.println("SecurityManager already set!");  
  11.             }  
  12.         try {  
  13.             //DataInputStream fis = new DataInputStream(new FileInputStream("input.txt"));  
  14.             BufferedReader fis = new BufferedReader(new FileReader("input.txt"));  
  15.             //DataOutputStream fos = new DataOutputStream( new FileOutputStream("output.txt"));  
  16.             BufferedWriter fos = new BufferedWriter(new FileWriter("output.txt"));  
  17.             String inputString;  
  18.             while ((inputString = fis.readLine()) != null) {  
  19.         //fos.writeBytes(inputString);  
  20.         //fos.writeByte('\n');  
  21.         fos.write(inputString);  
  22.         fos.write('\n');  
  23.             }  
  24.             fis.close();  
  25.             fos.close();  
  26.         } catch (IOException ioe) {  
  27.             System.out.println("I/O failed for SecurityManagerTest.");  
  28.         }catch(Exception e)  
  29.         {  
  30.            System.out.println(e.toString());  
  31.         }  
  32.         
  33.    }  
  34. }  
  35.    
  36.    
  37. import java.io.*;  
  38. class PasswordSecurityManager extends SecurityManager {  
  39. private String password;  
  40. PasswordSecurityManager(String password) {  
  41.     super();  
  42.     this.password = password;  
  43. }  
  44. private boolean accessOK() {  
  45.     int c;  
  46.     //DataInputStream dis = new DataInputStream(System.in);  
  47.     BufferedReader dis = new BufferedReader(new InputStreamReader(System.in));  
  48.     String response;  
  49.     System.out.println("What's the secret password?");  
  50.     try {  
  51.         response = dis.readLine();  
  52.         if (response.equals(password))  
  53.             return true;  
  54.         else  
  55.             return false;  
  56.     } catch (IOException e) {  
  57.         return false;  
  58.     }  
  59. }  
  60. public void checkRead(FileDescriptor filedescriptor) {  
  61.     if (!accessOK())  
  62.         throw new SecurityException("Not a Chance!");  
  63. }  
  64. public void checkRead(String filename) {  
  65.     if (!accessOK())  
  66.         throw new SecurityException("No Way!");  
  67. }  
  68. public void checkRead(String filename, Object executionContext) {  
  69.     if (!accessOK())  
  70.         throw new SecurityException("Forget It!");  
  71. }  
  72. public void checkWrite(FileDescriptor filedescriptor) {  
  73.     if (!accessOK())  
  74.         throw new SecurityException("Not!");  
  75. }  
  76. public void checkWrite(String filename) {  
  77.     if (!accessOK())  
  78.         throw new SecurityException("Not Even!");  
  79. }  
  80. }   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值