Search code examples
javasecurityexceptionpermissionspolicy

java security policy doesn't work as expected, always give AccessControlException


First, I've this working code:

import java.io.FileWriter;
import java.io.IOException;
public class TestPolicy {
    public static void main(String[] args) {
        FileWriter writer;
        try {
            writer = new FileWriter("testPolicy.txt");
            writer.write("hello1");
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

It runs well with

D:\Documents\myproject\mynet\mytest\java\security\target\classes>java -classpath . TestPolic

And it will generate a new file called [testPolicy.txt]

Then I added a ../../src/myPolicy.txt with content:

grant codeBase "file:D:\Documents\myproject\mynet\mytest\java\security\target\classes*" {
    permission java.io.FilePermission "testPolicy.txt", "read,write";
};

I expected, as long as I specified "read,write" permission, it should also run well. But it runs with exception:

D:\Documents\myproject\mynet\mytest\java\security\target\classes>java -classpath . -Djava.security.manager -Djava.security.policy=../../src/myPolicy.txt TestPolicy
Exception in thread "main" java.security.AccessControlException: access denied ("java.io.FilePermission" "testPolicy.txt" "write")
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkWrite(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileWriter.<init>(Unknown Source)
        at TestPolicy.main(TestPolicy.java:8)

Where did I get wrong, how to fix it?

Thanks a lot.


Solution

  • Use forward slashes instead of backslashes in the codeBase URL in your myPolicy.txt. You may also need a slash between the "classes" and the "*".

    Per the PolicyFiles documentation:

    Note: a codeBase value is a URL and thus should always utilize slashes (never backslashes) as the directory separator, even when the code source is actually on a Windows system. Thus, if the source location for code on a Windows system is actually C:\somepath\api\, then the policy codeBase entry should look like:

    grant codeBase "file:/C:/somepath/api/" {
        ...
    };