• 安全管理器入门小节


    1、关于安全管理器的概念:

    每个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()方法,执行栈检查 

    2、实现安全管理器步骤: 

    (1) 创建一个SecurityManager的子类; 

    (2) 覆盖一些方法。

    PasswordSecurityManager.java

    package com.lixx.security;

    import java.io.BufferedReader;

    import java.io.FileDescriptor;

    import java.io.IOException;

    import java.io.InputStreamReader;

    public 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!");  

    }  

    }

    TestSecurity.java

    package com.lixx.security;

    import java.io.BufferedReader;

    import java.io.BufferedWriter;

    import java.io.File;

    import java.io.FileReader;

    import java.io.FileWriter;

    import java.io.IOException;

    public class TestSecurity {

    public static void main(String args[])  

      {  

    System.out.println(new File("src/com/lixx/security/input.txt").exists());

           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());  

           }  

           

      }  

    }

    如果要手动地设置安全策略文件,可以以下面方式设置:

    System.setProperty ("java.security.policy",  PerfectTimeClient.class.getResource ("server.policy").toString ());  

    System.setSecurityManager(new RMISecurityManager()); 

  • 相关阅读:
    ArcEngine 地图与布局的联动
    ArcGIS Server安装篇
    AO+C#设置栅格图层基高 制作三维
    ArcGIS 10研究(一) 之 Desktop总体介绍 转载
    linux centos7 增加硬盘
    linux CentOS7安装oracle12c
    java中关于Socket类通信的基本测试程序
    Ubuntu 的中国梦
    我们无需“开始”菜单
    数据库战略高度解析 之系列说明
  • 原文地址:https://www.cnblogs.com/xinzhuangzi/p/4100464.html
Copyright © 2020-2023  润新知