如何为基于角色的 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,应该有注释可以让您摆脱部分配置,但自定义过滤器。
希望对您有所帮助。
我需要为我的 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,应该有注释可以让您摆脱部分配置,但自定义过滤器。
希望对您有所帮助。