Let’s start with the concept that there are actually security considerations in Java design, but they are rarely touched or used during development. So there’s not a lot of material on the subject, and what you find on the web is basically an introduction to the Java security model.

The example instructions used in this article are also excerpted from the above article.

The code of

Let’s take a look at how the Current Java security model is implemented, starting with code and throwing away all the concepts.

1. The premise

Two projects, one X project and one Y project

The X project has write permission for a directory that belongs to the X project (this permission is controlled by the Java security model, as discussed later)

Project Y calls the write file utility class in project X, and project Y does not grant write permission to a directory

2. The code block

X project (project path: D:\workspace\projectX\; The code path is in the project path bin directory. A directory: D: workspace\projectX\bin) :

package learn.java.security; import java.io.File; import java.io.IOException; import java.security.AccessControlException; import java.security.AccessController; import java.security.PrivilegedAction; Public class FileUtil {private final static String FOLDER_PATH = "D:\ workspace\ projectX\ bin"; Public static void makeFile(String fileName) {try {// Try to create A new File in the path of the project A execution File File fs = new File(FOLDER_PATH + "\\" + fileName); fs.createNewFile(); } catch (AccessControlException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }} public static void doPrivilegedAction (final String fileName) {/ / with privileged access to create a file the AccessController. The doPrivileged (new PrivilegedAction<String>() { @Override public String run() { makeFile(fileName); return null; }}); }}Copy the code

Y project (project path: D:\workspace\projectY\; The code path is in the project path bin directory.

package demo.security; import java.io.File; import java.io.IOException; import java.security.AccessControlException; import learn.java.security.FileUtil; public class DemoDoPrivilege { public static void main(String[] args) { System.out.println("***************************************"); System.out.println("I will show AccessControl functionality..." ); System.out.println("Preparation step : turn on system permission check..." ); / / open the System security permission check switch System. SetSecurityManager (new SecurityManager ()); System.out.println(); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); System.out.println(" Create a new file named temp1.txt via privileged action ..." ); / / privileged access method in engineering A execution path to the file to create temp1. TXT file FileUtil. DoPrivilegedAction (" temp1. TXT "); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); System.out.println(); System.out.println("/////////////////////////////////////////"); System.out.println("Create a new file named temp2.txt via File ..." ); TXT File fs = new File("D:\\workspace\\projectX\\bin\\temp2.txt"); fs.createNewFile(); } catch (IOException e) { e.printStackTrace(); } catch (AccessControlException e1) { e1.printStackTrace(); } System.out.println("/////////////////////////////////////////"); System.out.println(); System.out.println("-----------------------------------------"); System.out.println("create a new file named temp3.txt via FileUtil ..." ); Fileutil. makeFile("temp3. TXT "); System.out.println("-----------------------------------------"); System.out.println(); System.out.println("***************************************"); }}Copy the code

This is the end of the code. Now start authorization for security. Assume the following authorization policy file (mypolicy.txt) is in the root directory of project Y:

/ / authorization project X written in Java executable files in a directory file permissions grant codebase "file: / D: / workspace/projectX/bin" {permission Java. IO. FilePermission "D:\\workspace\\projectX\\bin\\*", "write"; };Copy the code

To specify the security file run program:

java -Djava.security.policy=.\\MyPolicy.txt -classpath D:\workspace\projectY\bin; D:\workspace\projectX\bin demo.security.DemoDoPrivilegeCopy the code

Execution Result:

*************************************** I will show AccessControl functionality... Preparation step : turn on system permission check... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create a new file named temp1.txt via privileged action ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //////////////////////////////////////// Create a new file named temp2.txt via File ... java.security.AccessControlException: Access denied (java.io.FilePermission D:\workspace\projectX\bin\temp2.txt write) at java.security.AccessController.checkPermission(AccessController.java:108) at java.lang.SecurityManager.checkPermission(SecurityManager.java:533) at java.lang.SecurityManager.checkWrite(SecurityManager.java:963) at java.io.File.createNewFile(File.java:882) at demo.security.DemoDoPrivilege.main(DemoDoPrivilege.java:32) //////////////////////////////////////// ---------------------------------------- create a new file named temp3.txt via FileUtil ... java.security.AccessControlException: Access denied (java.io.FilePermission D:\workspace\projectX\bin\temp3.txt write) at java.security.AccessController.checkPermission(AccessController.java:108) at java.lang.SecurityManager.checkPermission(SecurityManager.java:533) at java.lang.SecurityManager.checkWrite(SecurityManager.java:963) at java.io.File.createNewFile(File.java:882) at learn.java.security.FileUtil.makeFile(FileUtil.java:16) at demo.security.DemoDoPrivilege.main(DemoDoPrivilege.java:43) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *Copy the code

As can be seen from the execution result, when the safe mode takes effect, Y project cannot operate in the directory without permission either through the common interface (calling the code with permission) or through self-creation. The only way to succeed is through privileged AccessController.

As can be seen, in order to access secure resources, you must either have full permissions on the call chain (that is, you have the corresponding permissions) or have privileged access.

You’ve been talking about privileged access, but you’ve got a pretty good idea of privileged access in terms of implementation, but what is it actually?

3. Privileged access

There are two types of programs executing in Java: local code is trusted by default, and remote code is considered untrusted. In previous Versions of Java, untrusted remote code was sandboxed, with access restricted to jVM-specific run-time scopes and tightly controlled code access to local resources. Native code has access to all native resources. Effectively isolate remote code to prevent damage to the local system.

For a history of Java security mechanisms, see the link to security mechanisms above.

Up to now, security models have introduced the concept of domains. The code is loaded into different system domains and application domains. The system domain is responsible for interacting with key resources, and each application domain accesses various needed resources through the proxy of the system domain (for example, the Y project writes resources through the X project). Vm protected domains have different permissions. Class files that exist in the domain have all the permissions of the current domain (for example, the above X project has the permissions of the X domain but Y project does not)

Looking at the entire security model, the most common usage is the above API (doPrivileged), which can give a piece of trusted code the maximum permissions, even more than the application that calls it (for example, Y calls X, obviously more permissions than Y), and temporarily access more resources.

Application scenarios: Applications cannot access certain system resources, but must obtain these resources to complete functions. DoPrivileged allows the application to temporarily expand access beyond current domain limits.

How AccessController works:

In a thread call stack, when the checkPermission method of the AccessController is called by the most recently called program (as when the code above created the file), ACC decides whether to grant the algorithm for the access required by the program: 1. If one of the callers in the call chain does not have the required permission, throw an AccessControlException (as in the above code Y has no permission) 2. Authorization is granted if the following conditions are met

  • The caller accesses another method that has that permission and is marked as having access privileges (such as the privileged method Y calls X above)
  • Subsequent objects called (directly or indirectly) by the calling program have permissions (such as the above code X has permissions)