java - java.policy 授予 SocketPermission 时,为什么 ServerSocket.accept() 上出现 AccessControlException?
问题描述
尽管在 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" "accept,resolve")
服务器端错误信息中的端口,被理解为客户端表达式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());
}
实际结果是服务器上的 java.security.AccessControlException 而 accept 方法阻塞,而客户端上的 java.io.EOFException 从 java.io.InputStream 实例化 ObjectInputStream 时,这是一个 java.net.SocketInputStream。虽然 EOFException 是从 ObjectInputStream 构造函数中抛出的,但触发服务器的 AccessControlException 的是客户端的 Socket 实例。
预期的结果是服务器的 java.policy 中的 java.net.SocketPermission 授权被理解,没有 AccessControlException 并且在客户端从 java.io.InputStream 实例化 ObjectInputStream,这是一个 java.net.SocketInputStream,是成功的。
解决方案
像这样的权限条目没有任何问题
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/-"
推荐阅读
- html - html/css:用括号括起来的输入元素的表格/网格
- python - 并行计算-将每个进程输出到文件
- python - 如何从 Python 3 中的循环函数返回
- windows - 如何从任务栏堆栈中禁用/删除“关闭所有 Windows”选项?
- swift - 如何在 SQLite 中正确定义自定义函数的闭包
- razor - 具有 N 个嵌套项模板且无数据绑定的 Blazor 组件
- sql-server - 有没有办法加入日历表以开始和结束另一个查询的日期?
- excel - IE 点击没有关联链接的按钮(使用 Excel VBA)
- r-markdown - 在带有投影仪输出的 RMarkdown 中使用 tikzdevice
- python-3.x - Python Bokeh FileInput 小部件