Spring Data REST 中的身份验证和授权
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18989156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Authentication and authorization in Spring Data REST
提问by Rodrigo Guerra
I am implementing a Spring Data RESTbased app and I would like to know if there is an elegant way to implement authentication and authorization rules using this framework or related frameworks.
我正在实现一个基于Spring Data REST的应用程序,我想知道是否有一种优雅的方式来使用这个框架或相关框架来实现身份验证和授权规则。
All HTTP requests to the REST server must carry authentication headers, I need to check them and decide to authorize or not based on the HTTP method and the association of the authenticated user with the resource being requested. For example, (the app is the REST server of an e-learning system), the instructors can access only their own course sections, students can access only the courses sections they are subscribed, etc.
对 REST 服务器的所有 HTTP 请求都必须携带身份验证标头,我需要检查它们并根据 HTTP 方法以及经过身份验证的用户与所请求资源的关联来决定是否授权。例如,(该应用程序是电子学习系统的 REST 服务器),教师只能访问自己的课程部分,学生只能访问他们订阅的课程部分等。
I would like to know if there is a default way to implement authorization in Spring Data REST. If the answer is no, could you make a suggestion for my issue? I am thinking about:
我想知道在 Spring Data REST 中是否有默认的方式来实现授权。如果答案是否定的,您能否为我的问题提出建议?我在想:
- Servlet Filters
- Spring Security
- Spring Data REST Handlers (how to access the HTTP headers?)
- Servlet 过滤器
- 春季安全
- Spring Data REST 处理程序(如何访问 HTTP 标头?)
回答by Rakesh Waghela
The best bet for you is Spring Security. That would help you achieve authorization is much simpler manner.
最适合您的是 Spring Security。那将帮助您实现授权的方式要简单得多。
Spring Security would require you an implementation that looks at request headers and performs the log-in operation programmatically.
Spring Security 将需要您查看请求标头并以编程方式执行登录操作的实现。
Refer the accepted answer here.. I had followed the same and implemented the security layer in front of my rest services ( which were build using RestEasy )
请在此处参考接受的答案.. 我遵循相同的做法并在我的休息服务(使用 RestEasy 构建)前面实现了安全层
RESTful Authentication via Spring
There is an alternate method as well.. Refer http://www.baeldung.com/spring-security-authentication-provider
还有一种替代方法。请参阅 http://www.baeldung.com/spring-security-authentication-provider
In both cases you can disable the session creation by declaring the stateless authentication in spring security, this would help you improve the performance considerably when large volume of hits are made to the state-less REST services..
在这两种情况下,您都可以通过在 Spring Security 中声明无状态身份验证来禁用会话创建,这将帮助您在对无状态 REST 服务进行大量点击时显着提高性能。
回答by Alexey Lagunov
If you use Spring Method Security, you may want to place @Secured annotations on class level rather than on every method of your spring-data repositories. I did it this way:
如果您使用 Spring Method Security,您可能希望在类级别而不是在 spring-data 存储库的每个方法上放置 @Secured 注释。我是这样做的:
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;
}
}
And then I register it into spring security infrastructure:
然后我将它注册到 spring 安全基础设施中:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class CustomMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return new MethodLevelOverridesClassLevelSecurityMetadataSource();
}
}
And then I can forbid access to method findByModifiedAfterto ROLE_USER, but permit all repository methods for ROLE_ADMIN:
然后我可以禁止访问方法findByModifiedAfterto 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);
}

