无法评估带有字符串列表的 SpEL 表达式
SpEL expression with String list fails to be evaluated
10 月 27 日更新
以下方法具有基于 SpEL 的 ACL 注释。意思是检查fileId
的文件对象是否有Read
和Write
的权限。如果文件对象包含这两个权限中的任何一个,ACL通过,否则抛出异常。
@Component
public class ApiImpl {
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
public FileListVO getFiles(String fileId) {
...
}
}
注释通过下面的acl
组件。
public interface AclService {
boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains any of permissions) {
return true;
}
throw exception here
}
}
问题是,下面的 SpEL 表达式无法计算:
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
java.lang.IllegalArgumentException: Failed to evaluate expression '@acl.hasPermissions('File',{'Read','Write'}, #fileId)'
There is a List<String> permissions in it. What is the correct expression for this?
请注意 AclServiceImpl.hasPermissions()
中的 throw exception
行为是遗留代码,我不想更改。 @PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
预计 return true
不会抛出异常。我知道以下可能是一个选项,
public interface AclService {
boolean hasPermission(String type, String permission, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermission(String type, String permission, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains permission) {
return true;
}
return false; // not throw exception
}
}
@Component
public class ApiImpl {
@PreAuthorize("@acl.hasPermissions('File','Read', #fileId)"
+ "|| @acl.hasPermissions('File','Write', #fileId)")
@PostMeetingTelemetry()
public FileListVO getFiles(String fileId) {
...
}
}
但我只是想知道如何增强
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
这样下面的代码就可以工作了。
public interface AclService {
boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains any of permissions) {
return true;
}
throw exception here
}
}
@Component
public class ApiImpl {
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
public FileListVO getFiles(String fileId) {
...
}
}
throw exception here
当然,如果你在那里抛出异常,评估就会失败。
您应该 return false。
通过以下更改,它可以工作。不确定是否需要第 1 个更改,但第 2 个更改是必须的。
- 将
List<String>
替换为 String[]
以获得 permissions
- 将
{'Read','Write'}
替换为new String[]{'Read','Write'}
之前
public interface AclService {
boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains any of permissions) {
return true;
}
throw exception here
}
}
@Component
public class ApiImpl {
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
@PostMeetingTelemetry()
public FileListVO getFiles(String fileId) {
...
}
}
之后
public interface AclService {
// Replace List<String> with String[]
boolean hasPermissions(String type, String[] permissions, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermissions(String type, String[] permissions, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains any of permissions) {
return true;
}
throw exception here
}
}
@Component
public class ApiImpl {
// Replace {'Read','Write'} with new String[]{'Read','Write'}
@PreAuthorize("@acl.hasPermissions('File',new String[]{'Read','Write'}, #fileId)")
@PostMeetingTelemetry()
public FileListVO getFiles(String fileId) {
...
}
}
10 月 27 日更新
以下方法具有基于 SpEL 的 ACL 注释。意思是检查fileId
的文件对象是否有Read
和Write
的权限。如果文件对象包含这两个权限中的任何一个,ACL通过,否则抛出异常。
@Component
public class ApiImpl {
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
public FileListVO getFiles(String fileId) {
...
}
}
注释通过下面的acl
组件。
public interface AclService {
boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains any of permissions) {
return true;
}
throw exception here
}
}
问题是,下面的 SpEL 表达式无法计算:
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
java.lang.IllegalArgumentException: Failed to evaluate expression '@acl.hasPermissions('File',{'Read','Write'}, #fileId)'
There is a List<String> permissions in it. What is the correct expression for this?
请注意 AclServiceImpl.hasPermissions()
中的 throw exception
行为是遗留代码,我不想更改。 @PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
预计 return true
不会抛出异常。我知道以下可能是一个选项,
public interface AclService {
boolean hasPermission(String type, String permission, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermission(String type, String permission, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains permission) {
return true;
}
return false; // not throw exception
}
}
@Component
public class ApiImpl {
@PreAuthorize("@acl.hasPermissions('File','Read', #fileId)"
+ "|| @acl.hasPermissions('File','Write', #fileId)")
@PostMeetingTelemetry()
public FileListVO getFiles(String fileId) {
...
}
}
但我只是想知道如何增强
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
这样下面的代码就可以工作了。
public interface AclService {
boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains any of permissions) {
return true;
}
throw exception here
}
}
@Component
public class ApiImpl {
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
public FileListVO getFiles(String fileId) {
...
}
}
throw exception here
当然,如果你在那里抛出异常,评估就会失败。
您应该 return false。
通过以下更改,它可以工作。不确定是否需要第 1 个更改,但第 2 个更改是必须的。
- 将
List<String>
替换为String[]
以获得permissions
- 将
{'Read','Write'}
替换为new String[]{'Read','Write'}
之前
public interface AclService {
boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermissions(String type, List<String> permissions, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains any of permissions) {
return true;
}
throw exception here
}
}
@Component
public class ApiImpl {
@PreAuthorize("@acl.hasPermissions('File',{'Read','Write'}, #fileId)")
@PostMeetingTelemetry()
public FileListVO getFiles(String fileId) {
...
}
}
之后
public interface AclService {
// Replace List<String> with String[]
boolean hasPermissions(String type, String[] permissions, Object resource, Object... resourceContext);
}
@Component("acl")
public class AclServiceImpl implements AclService {
@Override
public boolean hasPermissions(String type, String[] permissions, Object resource, Object... resourceContext) {
List<String> resourcePermissions = get permissions of resource
if (resourcePermissions contains any of permissions) {
return true;
}
throw exception here
}
}
@Component
public class ApiImpl {
// Replace {'Read','Write'} with new String[]{'Read','Write'}
@PreAuthorize("@acl.hasPermissions('File',new String[]{'Read','Write'}, #fileId)")
@PostMeetingTelemetry()
public FileListVO getFiles(String fileId) {
...
}
}