1

我正在使用基于表达式的 Spring Security 3.x 保护我的应用程序。我有以下服务接口:

@PreAuthorize("hasRole('ROLE_ADMIN') or hasPermission(#employeeId, 'employee', 'isOwner')")
EmployeeData getById(Integer employeeId);

@PreAuthorize("hasRole('ROLE_ADMIN') or hasPermission(#employeeId, 'employee', 'isOwner')")
void update(Integer employeeId, EmployeeData employeedata);

我的 PermissionEvaluator 如下所示:

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
    private Map<String, Permission> permissionMap = new HashMap<String, Permission>();

    public CustomPermissionEvaluator(Map<String, Permission> permissionMap) {
        this.permissionMap = permissionMap;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        throw new PermissionNotDefinedException("Permission not supported for loaded domain object by " + this.getClass().toString());
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        verifyPermissionIsDefined((String) permission);
        return permissionMap.get(permission).isAllowed(authentication, (Integer) targetId);
    }

    private void verifyPermissionIsDefined(String permissionKey) {
        if (!permissionMap.containsKey(permissionKey)) {
            throw new PermissionNotDefinedException("No permission with key '" + permissionKey + "' is defined in" + this.getClass().toString());
        }
    }
}

对于第一个服务方法 (getById),它按预期工作:

  • 如果用户有 ROLE_ADMIN,那么他就可以获取数据。
  • 如果用户想查看自己的个人资料,他也可以

但是,对于第二种方法,更新方法,应用程序不起作用。targetId 在调用方法时始终为空hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission)

我不知道为什么。任何帮助,将不胜感激。

4

2 回答 2

3

请检查服务和实现中的参数名称是否匹配。

您还可以检查MethodSecurityEvaluationContext.lookupVariable方法如何与调试器一起使用。

查看类似的问题:spring security:为什么我们不能在 @PreAuthorize 中访问 Hibernate 实体参数?

于 2012-09-07T11:48:21.733 回答
0

我有类似的问题: targetDomainObject 每次 hasPermission 调用都为空。

对我来说,问题是我的接口 A 设置了所有身份验证注释(如 @PreAuthorize 和 @PostAuthorize)。它由抽象类 B 实现。具体类 C 是实际的服务。

public class C extends B

这没有用。

public class C extends B implements A

但这工作得很好。

从代码逻辑来看,这些声明是完全一样的。但是 Spring security 混淆了第一个
并且与第二个正常工作。

于 2015-01-09T19:29:03.947 回答