我一直在执行维护升级,这是一个最初为Java 2或3开发的旧Java应用程序(已有十多年历史),而且我遇到了一些已经杀了我一周的东西。
应用程序实现自己的名为PolicyManager的策略。该类扩展了javax.security.auth.Policy。文档告诉我,Java 4中的java.security.Policy被弃用了,所以我努力将其切换出来。我替换了导入并更新了getPermissions方法以接受java.security.ProtectionDomain,而不是javax.security.auth.Subject和java.security.CodeSource。
我的班级现在看起来像:
//import javax.security.auth.Policy;
import java.security.Policy;
public class PolicyManager extends Policy
{
@Override
public synchronized void refresh()
{
PermissionManager.getInstance().clearAll();
}
@Deprecated
public PermissionCollection getPermissions( Subject subject, CodeSource cs )
{
PermissionCollection permissions = null;
Iterator<?> iterator = subject.getPrincipals().iterator();
Principal principal = null;
while( iterator.hasNext() )
{
principal = (Principal)iterator.next();
PermissionCollection principalPerm = null;
try
{
principalPerm = PermissionManager.getInstance().
getPrincipalPermissions(principal.getClass().getName(),
principal.getName(), cs, false);
}
catch (SQLException ex)
{
continue;
}
if (permissions == null)
{
permissions = principalPerm;
}
else
{
Enumeration<?> en = principalPerm.elements();
Permission permission = null;
while( en.hasMoreElements() )
{
permission = (Permission)en.nextElement();
if ( !permissions.implies( permission ) )
{
permissions.add( permission );
}
}
}
}
return (permissions == null)?new Permissions():permissions;
}
public PermissionCollection getPermissions(ProtectionDomain pd)
{
PermissionCollection permissions = null;
List<Principal> principalList = new ArrayList<Principal>();
for (Principal test : pd.getPrincipals()) {
principalList.add(test);
}
Iterator<Principal> iterator = principalList.iterator();
Principal principal = null;
while( iterator.hasNext() )
{
principal = (Principal)iterator.next();
PermissionCollection principalPerm = null;
try
{
principalPerm = PermissionManager.getInstance().
getPrincipalPermissions(principal.getClass().getName(),
principal.getName(), pd.getCodeSource(), false);
}
catch (SQLException ex)
{
continue;
}
if (permissions == null)
{
permissions = principalPerm;
}
else
{
Enumeration<?> en = principalPerm.elements();
Permission permission = null;
while( en.hasMoreElements() )
{
permission = (Permission)en.nextElement();
if ( !permissions.implies( permission ) )
{
permissions.add( permission );
}
}
}
}
return (permissions == null)?new Permissions():permissions;
}
}
我的问题是,由于某种原因,这已经杀死了应用程序的所有权限检查。在更改内容以使用java.security.Policy类之后,似乎忽略了java安全策略文件。每当使用AccessController检查服务器操作的权限时,应用程序的ProtectionDomains都没有在security.policy文件中分配任何授权,并且我给出了java.security.AccessControlException : 拒绝访问。
我在部署期间没有收到任何警告或错误。它似乎无法找到该文件。这对我没有任何意义,因为我还没有改变任何配置文件或VM参数。为了进行调试,我使文件尽可能简单:
grant {
permission java.security.AllPermission;
};
仍然没有。当管理器延伸到java.security.Policy时,我甚至不确定应用程序是否正在尝试加载安全策略。我在我的VM参数中添加了-Djava.security.debug = policy,但没有任何结果。它似乎没有加载任何东西,甚至不是默认的Java策略。控制台是空白的。当我延伸到javax.security.auth.Policy时,我会看到你期望的一切 - 政策补助,评估等。
应用程序不使用安全管理器,但我确实尝试实现一个(通过VM参数-Djava.security.manager和代码与System.setSecurityManager(new SecurityManager());)只是为了看看是否帮助,只会让事情变得更糟 - 没有什么可以执行。 ojdbc6.jar在服务器启动时被拒绝测试数据库连接。
只需将上述类中的导入转换回javax.security.auth.Policy就可以解决所有问题。将其翻转会导致访问被拒绝错误,并且我的策略文件没有权限授予。我一直在阅读有关Java安全策略实现的所有内容,但我还没有找到解释这一点的任何内容。