领先一步
VMware 提供培训和认证,助您加速成长。
了解更多用户应参考Spring Security 参考文档,其中包含更及时的信息。
这是四部分博客系列文章的第三篇。在我的第一篇文章中,我介绍了 Spring Security Java 配置,并讨论了项目的一些具体细节。在上一篇文章中,我们通过一些示例讲解了如何配置基于 Web 的安全。
在本文中,我将讨论如何使用 Spring Security Java 配置来配置基于方法(Method based)的安全。与上一篇文章一样,我们将从一个非常基础的示例开始,然后逐步展示一个进行了一些定制的示例。
假设我们有一个名为 MethodSecurityService 的服务,如下所示(尽管它不是特别有趣)。
public interface MethodSecurityService {
@PreAuthorize("hasRole('ROLE_USER')")
String requiresUserRole();
}
我们的实现同样微不足道,但这将确保我们专注于 Spring Security,而不是我们的服务本身。
public class MethodSecurityServiceImpl implements
MethodSecurityService {
public String requiresUserRole() {
return "You have ROLE_USER";
}
}
通过使用 @EnableGlobalMethodSecurity
注解,我们可以轻松地使用 Java 配置来保护我们的方法。请注意,methodSecurityService
实际上不是我们安全配置的一部分,但我们必须使用 Spring 来创建 MethodSecurityService
,以便可以对其应用安全控制。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class HelloMethodSecurityConfig {
@Bean
public MethodSecurityService methodSecurityService() {
return new MethodSecurityServiceImpl()
}
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
}
这个配置与下面的 XML 配置非常相似
<global-method-security pre-post-annotations="enabled"/>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user" password="password" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
<beans:bean id="methodSecuriytService" class="MethodSecurityServiceImpl"/>
根据我们的配置,在 methodSecurityService bean 上调用 requiresUserRole() 方法将要求当前用户必须通过身份验证并拥有 "ROLE_USER" 角色。如果用户未通过身份验证或没有 "ROLE_USER" 角色,将抛出 AccessDeniedException。
@EnableWebSecurity
注解上有一些附加属性可用,但如果您希望以更高级的方式自定义方法安全,则需要继承 GlobalMethodSecurityConfiguration
。下面是一个我们自定义 PermissionEvaluator
的示例。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class CustomPermissionEvaluatorWebSecurityConfig extends GlobalMethodSecurityConfiguration {
@Bean
public MethodSecurityService methodSecurityService() {
return new MethodSecurityServiceImpl()
}
@Override
protected MethodSecurityExpressionHandler expressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
return expressionHandler;
}
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
}
这与下面的 XML 配置非常相似
<global-method-security pre-post-annotations="enabled">
<expression-handler ref="expressionHandler"/>
</global-method-security>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user" password="password" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
<beans:bean id="methodSecuriytService" class="MethodSecurityServiceImpl"/>
<beans:bean id="expressionHandler" class="CustomExpressionHandler"/>
我们已经给出了一些示例,说明如何使用 Spring Security Java 配置来保护应用程序的方法级别安全。您可以在 spring-security-javaconfig 项目的 GitHub 仓库中找到更多示例。
如果您遇到 Bug、有改进想法等,请不要犹豫提出!我们希望听到您的想法,以便在代码正式发布之前确保其完善。尽早试用新功能是回馈社区的一种良好而简单的方式。这也确保了您想要的功能能够存在并按照您期望的方式工作。
请在 Spring Security JIRA 中将任何问题或功能请求记录在 "Java Config" 分类下。在记录 JIRA 后,我们鼓励(但不强制要求)您通过 Pull Request 提交您的修改。您可以在贡献者指南中阅读更多关于如何操作的信息。
如果您对如何实现某些功能有疑问,请使用 Spring Security 论坛 或在 Stack Overflow 上使用 spring-security 标签提问(我会密切关注)。如果您对这篇博客有具体的评论或问题,请随时留言。使用适当的工具将有助于让每个人都更轻松。
您现在应该已经了解如何使用 Spring Security Java 配置支持来配置基于方法(Method based)的安全。在下一篇文章中,我们将通过 OAuth Java 配置概念验证来演示 Spring Security 如何设计用于扩展。