我正在实现一个基于Spring Data REST的应用程序,我想知道是否存在使用此框架或相关框架来实现身份验证和授权规则的优雅方法。
对REST服务器的所有HTTP请求都必须带有身份验证标头,我需要检查它们,并根据HTTP方法以及经过身份验证的用户与所请求资源的关联来决定是否授权。例如,(该应用是电子学习系统的REST服务器),讲师只能访问他们自己的课程部分,学生只能访问他们订阅的课程部分,等等。
我想知道在Spring Data REST中是否存在实现授权的默认方法。如果答案是否定的,您能对我的问题提出建议吗?我正在考虑:
最适合您的选择是Spring Security。这将以更简单的方式帮助您获得授权。
Spring Security将需要您一个实现,该实现查看请求标头并以编程方式执行登录操作。
请在此处引用已接受的答案。我也遵循相同的方法,并在我的rest服务(使用RestEasy构建)的前面实现了安全层]
RESTful Authentication via Spring
还有另一种方法。参考http://www.baeldung.com/spring-security-authentication-provider
[在两种情况下,您都可以通过在Spring安全性中声明无状态身份验证来禁用会话创建,当对无状态REST服务进行大量匹配时,这将帮助您显着提高性能。
如果使用Spring Method Security,您可能希望将@Secured批注放在类级别上,而不是放在spring数据存储库的每个方法上。我是这样做的:
public class MethodLevelOverridesClassLevelSecurityMetadataSource extends AbstractMethodSecurityMetadataSource {
private static final Set<String> ALL_POSSIBLE_ROLES = Sets.newHashSet("ROLE_USER", "ROLE_ADMIN");
private static final Set<ConfigAttribute> ALL_POSSIBLE_CONFIG_ATTRIBUTES = ALL_POSSIBLE_ROLES.stream()
.map(SecurityConfig::new)
.collect(Collectors.toSet());
private static final SecuredAnnotationSecurityMetadataSource securedAnnotationSource = new SecuredAnnotationSecurityMetadataSource();
@Override
public Collection<ConfigAttribute> getAttributes(Method method, Class<?> targetClass) {
Collection<ConfigAttribute> attributes = securedAnnotationSource.getAttributes(method, targetClass);
if (isNotEmpty(attributes)) {
return attributes;
}
Secured annotation = AnnotationUtils.findAnnotation(targetClass, Secured.class);
if (annotation == null) {
return Collections.emptySet();
}
return Arrays.stream(annotation.value())
.map(SecurityConfig::new)
.collect(Collectors.toSet());
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return ALL_POSSIBLE_CONFIG_ATTRIBUTES;
}
}
然后我将其注册到Spring Security基础结构中:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class CustomMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return new MethodLevelOverridesClassLevelSecurityMetadataSource();
}
}
然后我可以禁止访问方法findByModifiedAfter
至ROLE_USER
,但允许使用ROLE_ADMIN
的所有存储库方法:
@Repository
@RepositoryRestResource(path = "users")
@Secured("ROLE_ADMIN")
interface UserRepository extends JpaRepository<User, Long>, QuerydslPredicateExecutor<User> {
int deleteByCheckedIsLessThan(LocalDateTime expirationDate);
@Secured("ROLE_USER")
Page<User> findByModifiedAfter(LocalDateTime modified, Pageable pageable);
}