如何为基于角色的 url/method 访问集成 Spring 安全性

How to integrate Spring Security for Role based url/method access

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

结果 class 仅包含为用户生成的令牌,他将在每个请求中传递该令牌。

现在知道如果用户处于特定角色

,我应该做哪些更改来限制 API 的访问

例如,如果我想限制 API findById 只有属于 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());
}

您需要做的是调整 Spring 安全配置。下面是一个带有 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: in your case you'll have to provide a 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 拦截,因此您需要在类路径中提供这些方面。

此外,请记住这不是完整的配置:需要 非常 很长 post 来连接所有东西:这只是一个关于如何开始。

有关更深入的信息,请参考 Spring 安全文档本身。

最后说明:如果您使用 JvaConfig 而不是 XML,应该有注释可以让您摆脱部分配置,但自定义过滤器。

希望对您有所帮助。