【问题标题】:How to integrate Spring Security for Role based url/method access如何为基于角色的 url/方法访问集成 Spring Security
【发布时间】:2016-03-30 14:14:50
【问题描述】:

我需要为我的 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 的访问

例如,如果我想限制 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());
}

【问题讨论】:

  • 我处理基于自定义令牌的身份验证 @RequestMapping(value = "login", method = RequestMethod.POST) public @ResponseBody Result login(@RequestBody Credentials credentials) { return loginService.login(credentials.getUsername (),credentials.getPassword()); }
  • 请不要解释配置,而是发布它 :-) 如果您这样做,您将得到更准确的答案。
  • 感谢@StefanoCazzola。我做了一些更改并添加了更多信息。

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


【解决方案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 security @PreAuthorize 和其他注释通过 AOP 被拦截,因此您需要在类路径中提供这些方面。

另外,请记住,这不是完整的配置:需要一个 非常 长的帖子来连接所有内容:这只是一个关于如何开始的示例。

如需更深入的信息,请参阅 Spring Security 文档本身。

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

希望对你有帮助。

【讨论】:

  • 感谢 Stefano 的提示。我完全根据您的 xml 配置设置了 java 配置环境,并为我的应用程序集成了 spring 安全功能。我做的另一件事是我在我的应用程序中添加了一个过滤器,它在 SecurityContextHolder.getContext 中添加了一个身份验证,因为我使用了基于令牌的身份验证,并且对于下一次调用,状态丢失了,我需要重建状态以便 @PreAuthorize 工作很好。
猜你喜欢
  • 2017-10-19
  • 1970-01-01
  • 2019-08-08
  • 2018-11-28
  • 1970-01-01
  • 2017-05-17
  • 2012-02-29
  • 1970-01-01
  • 2011-04-25
相关资源
最近更新 更多