Java RMI 访问控制异常:拒绝访问
-
19-09-2019 - |
题
嘿,我得到了一个 AccessControlException: access denied
当尝试启动我正在编写的 RMI 应用程序时,我无法弄清楚为什么如果我在默认端口 1099 或另一个动态端口上打开它,我会收到此异常,我的策略文件当前授予一切(将在以下情况下更改)应用程序已完成)。
我不知道哪里出了问题,任何帮助都会很有用
我的代码
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException {
if (System.getSecurityManager() == null)
{
System.setSecurityManager ( new RMISecurityManager() );
}
CreditCardServer ccs = new CreditCardServer();
int port = 1099;
try {
port = Integer.valueOf(args[0]);
}
catch (Exception e)
{
System.out.println("Invlaid Port");
}
if (((port <= 65535) && (port >= 49152)) || port ==1099)
{
System.out.println("Valid Port");
}
else
{
port = 1099;
System.out.println("Port not in Dynamic Range 49152<-->65535");
}
System.out.println(port);
LocateRegistry.createRegistry(port);
LocateRegistry.getRegistry().bind("CreditCardServer", ccs);
while (true)
{
//hum?
}
}
}
堆栈跟踪
vega3 [ia32.linux] 23% java -Djava.security.policy=wideopen.policy -jar "BookStore-CreditCardServer.jar 65000"
有效端口
65000
Exception in thread "main" java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:342)
at java.security.AccessController.checkPermission(AccessController.java:553)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051)
at java.net.Socket.connect(Socket.java:536)
at java.net.Socket.connect(Socket.java:492)
at java.net.Socket.<init>(Socket.java:389)
at java.net.Socket.<init>(Socket.java:203)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:146)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340)
at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
at bookstorecreditcardserver.Main.main(Main.java:56)
我的政策文件
grant {
// Allow everything for now
permission java.security.AllPermission;
};
解决方案 2
基本上,我笨,我认为因为Java没有抱怨有人找到.policy文件AOK,原来它是不动the.policy文件的新副本到工作目录可以解决所有:-D
其他提示
我一直停留在这个一整天(后搞清楚我不得不开始从命令行rmiregistry中),努力使这项工作与Eclipse本地,终于解决了这个问题。几个指针救别人这样残酷的命运:
1 - 正确分配策略文件,无论是与一个命令行标志:
java -Djava.security.policy=/home/.../<filename>.policy ...
或通过将这个直接在您的代码:
System.setProperty("java.security.policy","file:///home/.../<filename>.policy");
您也可以把它放在同一文件夹中的项目的根),以减少对URI
file:./<filename>.policy
(使用相对的而不是绝对URI - 我其实不明白这一点,直到今天)
。2 - 确保政策文件的格式是正确的,e.g:
grant codeBase "file:<path>/bin/-" {
permission java.security.AllPermission;
};
这应该是指在您的二进制文件所在的文件夹!该政策文件的格式进行彻底的解释是
这就是它,我也建议本教程,我发现它非常有帮助,以获得正确的轨道上。
我发现关于这个主题的大多数答案都含糊且无益,并花了几个小时对此进行调试。您的错误很可能是因为策略文件格式不正确,或者您没有将其正确设置为命令行参数。
如果你得到一个 java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")
- 创建一个具有所有权限的安全策略文件,只是为了测试一下
grant codeBase "file:/-" {
permission java.security.AllPermission;
};
将此安全文件用于客户端和服务器,只是为了使其运行。
确保你没有任何错别字。我花了几个小时试图弄清楚为什么它不起作用,并且我输入了 -Djava.rmi.security.policy 而不是 -Djava.security.policy=...
对于我们这些只想从 Oracle 获取并运行 RMI 教程的人来说,此安全策略对于该示例来说已经足够了。