Java 允许任何人使用受保护的Spring Rest存储库中的方法

Java 允许任何人使用受保护的Spring Rest存储库中的方法,java,spring-security,spring-data-rest,Java,Spring Security,Spring Data Rest,我正在一个Spring Boot项目中使用Spring数据Rest和Spring安全性。 我有一个安全注释,允许ADMIN用户在类级别执行所有方法:@PreAuthorize(“hasAuthority('ADMIN')”) 我只想要这个存储库的一个方法(findByPersonalNumber),它在Spring安全身份验证过程中使用(cfuserdetailssservice),没有任何安全性 @RepositoryRestResource(collectionResourceRel = "

我正在一个Spring Boot项目中使用Spring数据RestSpring安全性。 我有一个安全注释,允许
ADMIN
用户在类级别执行所有方法:
@PreAuthorize(“hasAuthority('ADMIN')”)

我只想要这个存储库的一个方法(
findByPersonalNumber
),它在Spring安全身份验证过程中使用(cf
userdetailssservice
),没有任何安全性

@RepositoryRestResource(collectionResourceRel = "users", path = "users")
@PreAuthorize("hasAuthority('ADMIN')")
public interface UserRepository extends CrudRepository<User, Integer> {

    @PreAuthorize("permitAll()")
    @RestResource(exported = false)
    Optional<User> findByPersonalNumber(String personalNumber);
}

@Service
public class AuthenticationService implements UserDetailsService {

    private final UserRepository userRepository;

    @Inject
    public AuthenticationService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.getByPersonalNumber(username);
        return new CurrentUser(user);
    }
}

我还尝试了带有
isAnonymous()
值的
@PreAuthorize
注释,但没有更好的结果。

您已经预先授权了整个接口,更改单个方法安全性不允许您绕过它。我建议进行重构,将该方法移动到一个更公开的接口。@robinjonson我希望将我的所有方法保留在同一个存储库接口中。也许我可以删除整个界面中的预授权,覆盖所有方法,在每个方法上添加预授权注释,但我想找到一种更干净的方法。然后你必须在每个方法上设置整个预授权查询<代码>@PreAuthorize(“hasAuthority('ADMIN')&&¤tUserService.canAccessUser(主体,#id)”)
2015-08-13 10:11:02.989 DEBUG 1654 --- [nio-8080-exec-4] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2015-08-13 10:11:11.193 DEBUG 1654 --- [nio-8080-exec-4] .PrePostAnnotationSecurityMetadataSource : @org.springframework.security.access.prepost.PreAuthorize(value=permitAll()) found on specific method: public final java.util.Optional com.sun.proxy.$Proxy116.findByPersonalNumber(java.lang.String)
2015-08-13 10:11:11.193 DEBUG 1654 --- [nio-8080-exec-4] m.DelegatingMethodSecurityMetadataSource : Caching method [CacheKey[com.sun.proxy.$Proxy116; public abstract java.util.Optional xxx.repositories.UserRepository.findByPersonalNumber(java.lang.String)]] with attributes [[authorize: 'permitAll()', filter: 'null', filterTarget: 'null']]
2015-08-13 10:11:11.193 DEBUG 1654 --- [nio-8080-exec-4] .PrePostAnnotationSecurityMetadataSource : @org.springframework.security.access.prepost.PreAuthorize(value=permitAll()) found on specific method: public abstract java.util.Optional com.dassault_systemes.diy.repositories.UserRepository.findByPersonalNumber(java.lang.String)
2015-08-13 10:11:11.193 DEBUG 1654 --- [nio-8080-exec-4] m.DelegatingMethodSecurityMetadataSource : Caching method [CacheKey[org.springframework.data.jpa.repository.support.SimpleJpaRepository; public abstract java.util.Optional xxx.repositories.UserRepository.findByPersonalNumber(java.lang.String)]] with attributes [[authorize: 'permitAll()', filter: 'null', filterTarget: 'null']]
2015-08-13 10:11:11.193 DEBUG 1654 --- [nio-8080-exec-4] o.s.s.a.i.a.MethodSecurityInterceptor    : Secure object: ReflectiveMethodInvocation: public abstract java.util.Optional xxx.repositories.UserRepository.findByPersonalNumber(java.lang.String); target is of class [com.sun.proxy.$Proxy116]; Attributes: [[authorize: 'permitAll()', filter: 'null', filterTarget: 'null']]
2015-08-13 10:11:11.194 DEBUG 1654 --- [nio-8080-exec-4] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.authentication.InternalAuthenticationServiceException
2015-08-13 10:11:11.195 ERROR 1654 --- [nio-8080-exec-4] w.a.UsernamePasswordAuthenticationFilter : An internal error occurred while trying to authenticate the user.

org.springframework.security.authentication.InternalAuthenticationServiceException: An Authentication object was not found in the SecurityContext
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:110)
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:132)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:92)
    [...]
Caused by: org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:339)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:198)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:60)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy119.findByPersonalNumber(Unknown Source)
    at com.dassault_systemes.diy.service.UserServiceImpl.getByPersonalNumber(UserServiceImpl.java:37)
    at com.dassault_systemes.diy.service.AuthenticationService.loadUserByUsername(AuthenticationService.java:35)