如何将Spring Security集成到基于角色的URL /方法访问中

时间:2016-03-26 13:46:01

标签: spring-mvc spring-security spring-4

我需要为我的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());
}

1 个答案:

答案 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元素。您可以通过扩展Sp​​ring类然后自定义其行为来轻松地完成它

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,那么应该有注释可以摆脱你的部分配置,但是自定义过滤器。

希望它有所帮助。