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