我见过通过在Privilege块中执行的Reflection获取字段值的代码。以下代码段取自ReflectionUtil
:
public static <T> T accessDeclaredField(final Field f, final Object o, final Class<T> responseClass) {
return AccessController.doPrivileged(new PrivilegedAction<T>() {
public T run() {
boolean b = f.isAccessible();
try {
f.setAccessible(true);
return responseClass.cast(f.get(o));
} catch (SecurityException e) {
return null;
} catch (IllegalAccessException e) {
return null;
} finally {
f.setAccessible(b);
}
}
});
}
我不理解在特权区块中获取字段值的原因;我们可以不用它来做到这一点。
这是更好的编码练习还是我们获得额外的东西?
答案 0 :(得分:7)
如果没有安装安全管理器,您不需要特权块。但是,如果您正在编写完整的通用库代码(可能已使用安全管理器执行),并且库的调用者可能没有所需的权限,那么在没有PrivilegedAction
的情况下,您的代码将被拒绝访问好吧,即使代码本身(它的CodeSource)确实有权限。
答案 1 :(得分:2)
是的,您获得了使用调用类的权限调用PrivilegedAction
的好处,即使代码(在本例中为方法accessDeclaredField
)由没有的外部代码调用这些权限。
如果不使用AccessController.doPrivileged
,那么如果某些代码X调用ReflectionUtils
API来访问声明的字段而代码X没有安全权限suppressAccessChecks
,那么该操作将失败并且安全例外。
通过将操作包装在AccessController.doPrivileged
内,ReflectionUtils
标记其操作应使用其拥有权限执行,即使调用代码X没有这些权限也是如此。