为什么当java.policy授予SocketPermission时ServerSocket.accept()上的AccessControlException?

时间:2019-01-07 22:11:12

标签: java

尽管在java.policy中授予了SocketPermission,也会在ServerSocket.accept()上抛出AccessControlException。

出于修改目的,假设服务器IP地址为1.2.3.4,客户端IP地址为5.6.7.8。

服务器上的java.policy具有授予权限。

grant codeBase "file:C:/workspaces/gitlab/QMT-beachhead/QMT-beachhead/lib/-"{
  permission java.net.SocketPermission "5.6.7.8:1024-", "accept";
};

其他几种方法也尝试过相同的效果:

permission java.net.SocketPermission "5.6.7.8", "accept";
permission java.net.SocketPermission "5.6.7.8:*", "accept";
permission java.net.SocketPermission "5.6.7.8:0", "accept";

最近的尝试在驱动器号之前添加了缺少的斜杠。

file:/C:/workspaces/gitlab/QMT-beachhead/QMT-beachhead/lib/-

所有结果都类似:

java.security.AccessControlException访问被拒绝(“ java.net.SocketPermission”“ 5.6.7.8:50838”“接受,解决”)

服务器端错误消息中的端口(每次被理解为来自客户端表达式client.getLocalPort()的返回值)每次都不同。

在服务器上

private java.net.ServerSocket server;
private java.net.Socket connection;

try {
  connection = server.accept();
  }
catch (SecurityException e) {
  System.err.println(e.getClass().getName() + " " + e.getMessage());
}

在客户端上

private java.net.Socket client;
private java.io.ObjectInputStream input;

try {
  byte[] addr = {(byte)1, (byte)2, (byte)3, (byte)4};
  client = new java.net.Socket(java.net.InetAddress.getByAddress(addr), 16838);
  java.io.InputStream is = client.getInputStream();
  input = new ObjectInputStream(is);
}
  catch (java.io.IOException e) {
  System.err.println(e.getClass().getName());
}

实际结果是,当accept方法阻塞时,服务器上的java.security.AccessControlException;从java.net.SocketInputStream实例化ObjectInputStream时,客户端的java.io.EOFException。尽管EOFException是从ObjectInputStream构造函数抛出的,但客户端的Socket实例化才触发服务器的AccessControlException。

预期结果是可以理解服务器java.policy中的java.net.SocketPermission授予,不存在AccessControlException,并且从java.io.InputStream实例化客户端上的ObjectInputStream,这是一个java.net .SocketInputStream成功。

1 个答案:

答案 0 :(得分:0)

像这样的权限条目没有错

permission java.net.SocketPermission "5.6.7.8:1024-", "accept";

codeBase值需要更多注意。 1.2.3.4的所有者已验证代码源位置在目录树中

C:\workspaces\gitlab\QMT-beachhead\QMT-beachhead\lib\

有一些代码,但是需要SocketPermission的代码在目录树中

C:\workspaces\gitlab\QMT-beachhead\QMT-beachhead\bin\

此外,根据https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html#FileSyntax中的文档,在驱动器号之前需要加斜杠。 codeBase字段变为

codeBase "file:/C:/workspaces/gitlab/QMT-beachhead/QMT-beachhead/bin/-"