Spring - SpEL evaluates entity argument as null reference in @PreAuthorize(“hasPermission”)

[亡魂溺海] 提交于 2019-11-28 05:37:25

问题


I've got problem that SpEL is evaluating entity argument as null reference in the second method of this repository. This first method works well and id is correctly evaluated to Long as should be.

@NoRepositoryBean
public interface SecuredPagingAndSortingRepository<T extends AuditedEntity, ID extends Serializable>
        extends PagingAndSortingRepository<T, ID> {

    @Override
    @RestResource(exported = false)
    @PreAuthorize("hasPermission(#id, null, 'owner')")
    void delete(ID id);

    @Override
    @PreAuthorize("hasPermission(#entity, 'owner')")
    void delete(T entity);
}

This is my custom PermissionEvaluator:

@Slf4j
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {

    private final PermissionResolverFactory permissionResolverFactory;

    @Autowired
    public CustomPermissionEvaluator(PermissionResolverFactory permissionResolverFactory) {
        this.permissionResolverFactory = permissionResolverFactory;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        Assert.notNull(userDetails, "User details cannot be null");
        Assert.notNull(targetDomainObject, "Target object cannot be null");
        log.debug("Permmission: " + permission + " check on: " + targetDomainObject + " for user: " + userDetails.getUsername());

        PermissionType permissionType = PermissionType.valueOf(((String) permission).toUpperCase());
        return permissionResolverFactory.getPermissionResolver(permissionType).resolve(targetDomainObject.getClass(), authentication, (AuditedEntity) targetDomainObject);
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        // TODO
        return false;
    }
}

This test doesn't pass because of assert that target object cannot be null in CustomPermissionEvaluator.

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
@ContextConfiguration(classes = SqapApiApplication.class)
public class PermissionsIT {
    @Autowired
    private TestGroupRepository testGroupRepository;

    @Autowired
    private UserRepository userRepository;

    UserEntity user;

    @Before
    public void before() {
        user = new UserEntity("user", "password1", true, Sets.newHashSet(RoleType.ROLE_USER));
        user = userRepository.save(user);
    }

    @Test
    @WithMockUser(username="user")
    public void shouldDeleteWhenIsOwner() throws Exception {
        TestGroupEntity testGroupEntity = new TestGroupEntity("testGroup", "testdesc", Sets.newHashSet(new AbxTestEntity(1, "abx", "desc", null)));
        user.addTestGroup(testGroupEntity);
        user = userRepository.save(user);
        TestGroupEntity createdEntity = testGroupRepository.findAll().iterator().next();
        testGroupRepository.delete(createdEntity);
    }
}

回答1:


When referencing method parameters from spel in interfaces it pays to annotate them with Spring Data's @Param to explicitly name them:

@PreAuthorize("hasPermission(#entity, 'owner')")
void delete(@Param("entity") T entity);

If the parameters aren't annotated Spring has to use reflection to discover the parameter names. This is only possible for interface methods if

  • You're running Spring 4+
  • You're running Java 8
  • The interface was compiled with JDK 8 and the -parameters flag was specified

For class methods Spring has another option—it can use debug information. This works in Spring 3 and earlier versions of Java, but again it relies on a compile time flag to work (i.e. -g).

For portability it's better to annotate all the parameters you need to reference.

Reference: Access Control using @PreAuthorize and @PostAuthorize.



来源:https://stackoverflow.com/questions/41353363/spring-spel-evaluates-entity-argument-as-null-reference-in-preauthorizehasp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!