我需要为我的REST API提供基于角色的访问权限,我已经看到我们可以使用@PreAuthorize, @Secured
来实现这一点。但是我不确定应该做出哪些更改并将其设置为当前我使用custom token based authentication mechanism
为会话生成令牌并自行处理。
@RequestMapping(value = "login", method = RequestMethod.POST)
public @ResponseBody Result login(@RequestBody Credentials credentials) {
return loginService.login(credentials.getUsername(), credentials.getPassword());
}
Result类只包含一个为每个请求传递的用户生成的令牌。
现在知道如果用户具有特定角色
,我应该做出哪些更改来限制API的访问例如,如果我想限制用户只有findById
成员才能访问API ADMIN_ROLE
,那么我将不得不添加PreAuthorize
注释但不确定这将如何确定用户角色并自动阻止用户。
@PreAuthorize("ADMIN_ROLE")
@RequestMapping(value = "{id}", method = RequestMethod.GET)
public @ResponseBody Group findById(@PathVariable int id) {
return groupParser.getGroupById(id, groupService.getGroupTree());
}
答案 0 :(得分:1)
您需要做的是调整Spring Security配置。下面是一个带有XML配置的例子(我已经习惯了它);但是,它也可以在JavaConfig中使用。
基本上,
触发了Spring安全性<http ....>
...
</http>
元素。你需要像那样(或类似的东西)写它
<beans:bean id="authenticatedVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter">
<beans:property name="expressionHandler" ref="..." />
</beans:bean>
<beans:bean id="roleVoter"
class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value="" /> <!-- if you want to customize role prefix -->
</beans:bean>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg>
<beans:list>
<beans:ref bean="roleVoter" />
<beans:ref bean="authenticatedVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
<!-- use-expressions enables the @PreAuthorize -->
<http use-expressions="true" access-decision-manager-ref="accessDecisionManager">
....
</http>
注意添加的bean:它们是三个Spring组件。
第一个包含未指定的参考。它需要实施SecurityExpressionHandler的内容:在您的情况下,您必须提供DefaultMethodSecurityExpressionHandler
然后,要添加自定义令牌配置,您需要编写自己的过滤器并将其连接到HTTP
元素。您可以通过扩展Spring类然后自定义其行为来轻松地完成它
public class MyClientAuthenticationFilter extends OncePerRequestFilter {
....
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
// custom logics here
// throw exception for not authenticated
}
}
然后连线
<bean class="x.y.z.MyClientAuthenticationFilter" id="myClientAuthenticationFilter" />
<http ....>
<custom-filter ref="myClientAuthenticationFilter" before="BASIC_AUTH_FILTER" />
</http>
你应该基本完成。
请记住在构建中包含spring-security-aspects
:Spring安全@PreAuthorize
和其他注释都是通过AOP拦截的,因此您需要在类路径中提供这些方面。
此外,请记住,这不是完整的配置:它需要一个非常长的帖子来连接所有内容:这是一个关于如何开始的例子。
对于更深入的信息,请依赖Spring Security文档本身。
最后注意:如果你使用的是JvaConfig而不是XML,那么应该有注释可以摆脱你的部分配置,但是自定义过滤器。
希望它有所帮助。