总览

最近,我正在一个使用REST服务层与客户端应用程序(GWT应用程序)进行通信的项目中。 因此,我花了很多时间来弄清楚如何使用Spring Security保护REST服务。 本文介绍了我找到的解决方案,并已实现。 我希望此解决方案将对某人有所帮助,并节省大量宝贵的时间。

解决方案

在普通的Web应用程序中,每当访问安全资源时,Spring Security都会检查当前用户的安全上下文,并决定将其转发到登录页面(如果用户未通过身份验证),或将其转发到未经授权的资源。页面(如果他没有所需的权限)。

在我们的场景中,这是不同的,因为我们没有要转发的页面,我们需要调整和覆盖Spring Security以仅使用HTTP协议状态进行通信,下面我列出了使Spring Security发挥最大作用的工作:

  • 身份验证将通过普通形式的登录名进行管理,唯一的区别是响应将以JSON以及HTTP状态(可通过代码200(如果通过验证)或代码401(如果身份验证失败))进行;
  • 重写AuthenticationFailureHandler以返回代码401 UNAUTHORIZED;
  • 重写AuthenticationSuccessHandler以返回代码20 OK,HTTP响应的主体包含当前已认证用户的JSON数据;
  • 重写AuthenticationEntryPoint以始终返回代码401 UNAUTHORIZED。 这将覆盖Spring Security的默认行为,该行为是在用户不符合安全要求的情况下将用户转发到登录页面,因为在REST上我们没有任何登录页面;
  • 覆盖LogoutSuccessHandler以返回代码20 OK;

就像由Spring Security保护的普通Web应用程序一样,在访问受保护的服务之前,必须首先通过向登录URL提交密码和用户名来进行身份验证。

注意:以下解决方案要求Spring Security的最低版本为3.2。

覆盖AuthenticationEntryPoint

该类扩展了org.springframework.security.web.AuthenticationEntryPoint,并且仅实现了一种方法,该方法会在未经授权的情况下发送响应错误(带有401状态代码)。

@Component
public class HttpAuthenticationEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response,AuthenticationException authException) throws IOException {response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());}
}

重写AuthenticationSuccessHandler

AuthenticationSuccessHandler负责成功认证后的操作,默认情况下它将重定向到URL,但在我们的情况下,我们希望它发送带有数据的HTTP响应。

@Component
public class AuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {private static final Logger LOGGER = LoggerFactory.getLogger(AuthSuccessHandler.class);private final ObjectMapper mapper;@AutowiredAuthSuccessHandler(MappingJackson2HttpMessageConverter messageConverter) {this.mapper = messageConverter.getObjectMapper();}@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,Authentication authentication) throws IOException, ServletException {response.setStatus(HttpServletResponse.SC_OK);NuvolaUserDetails userDetails = (NuvolaUserDetails) authentication.getPrincipal();User user = userDetails.getUser();userDetails.setUser(user);LOGGER.info(userDetails.getUsername() + " got is connected ");PrintWriter writer = response.getWriter();mapper.writeValue(writer, user);writer.flush();}
}

重写AuthenticationFailureHandler

AuthenticationFaillureHandler负责身份验证失败后的处理方法,默认情况下它将重定向到登录页面URL,但是在我们的情况下,我们只希望它发送带有401 UNAUTHORIZED代码的HTTP响应。

@Component
public class AuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,AuthenticationException exception) throws IOException, ServletException {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);PrintWriter writer = response.getWriter();writer.write(exception.getMessage());writer.flush();}
}

覆盖LogoutSuccessHandler

LogoutSuccessHandler决定用户成功注销后的操作,默认情况下它将重定向到登录页面URL,因为我们没有重写它以返回带有20 OK代码的HTTP响应。

@Component
public class HttpLogoutSuccessHandler implements LogoutSuccessHandler {@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)throws IOException {response.setStatus(HttpServletResponse.SC_OK);response.getWriter().flush();}
}

Spring安全配置

这是最后一步,将所有工作放在一起,我更喜欢使用新的方式来配置Spring Security,它使用Java而不是XML,但是您可以轻松地将此配置适应XML。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {private static final String LOGIN_PATH = ApiPaths.ROOT + ApiPaths.User.ROOT + ApiPaths.User.LOGIN;@Autowiredprivate NuvolaUserDetailsService userDetailsService;@Autowiredprivate HttpAuthenticationEntryPoint authenticationEntryPoint;@Autowiredprivate AuthSuccessHandler authSuccessHandler;@Autowiredprivate AuthFailureHandler authFailureHandler;@Autowiredprivate HttpLogoutSuccessHandler logoutSuccessHandler;@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Bean@Overridepublic UserDetailsService userDetailsServiceBean() throws Exception {return super.userDetailsServiceBean();}@Beanpublic AuthenticationProvider authenticationProvider() {DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();authenticationProvider.setUserDetailsService(userDetailsService);authenticationProvider.setPasswordEncoder(new ShaPasswordEncoder());return authenticationProvider;}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.authenticationProvider(authenticationProvider());}@Overrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authenticationProvider(authenticationProvider()).exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and().formLogin().permitAll().loginProcessingUrl(LOGIN_PATH).usernameParameter(USERNAME).passwordParameter(PASSWORD).successHandler(authSuccessHandler).failureHandler(authFailureHandler).and().logout().permitAll().logoutRequestMatcher(new AntPathRequestMatcher(LOGIN_PATH, "DELETE")).logoutSuccessHandler(logoutSuccessHandler).and().sessionManagement().maximumSessions(1);http.authorizeRequests().anyRequest().authenticated();}
}

这是总体配置的一个潜行高峰,我在本文中附加了一个Github存储库,其中包含示例项目https://github.com/imrabti/gwtp-spring-security 。

我希望这可以帮助一些努力寻找解决方案的开发人员,请随时提出任何问题,或发布任何可以使该解决方案更好的增强功能。

翻译自: https://www.javacodegeeks.com/2014/09/secure-rest-services-using-spring-security.html

使用Spring Security保护REST服务相关推荐

  1. 将Spring Security OAuth2授权服务JWK与Consul 配置中心结合使用

    将Spring Security OAuth2授权服务JWK与Consul 配置中心结合使用 概述 在前文中介绍了OAuth2授权服务简单的实现密钥轮换,与其不同,本文将通过Consul实现我们的目的 ...

  2. tomcat使用ssl_使用SSL和Spring Security保护Tomcat应用程序的安全

    tomcat使用ssl 如果您看过我的上一个博客,您会知道我列出了Spring Security可以做的十件事 . 但是,在开始认真使用Spring Security之前,您真正要做的第一件事就是确保 ...

  3. 使用SSL和Spring Security保护Tomcat应用程序的安全

    如果您看过我的上一个博客,您会知道我列出了Spring Security可以做的十件事 . 但是,在认真开始使用Spring Security之前,您真正要做的第一件事就是确保您的Web应用使用正确的 ...

  4. 使用Spring Security对RESTful服务进行身份验证

    1.概述 本文重点介绍如何针对提供安全服务的安全REST API进行身份验证 -主要是RESTful用户帐户和身份验证服务. 2.目标 首先,让我们看一下参与者-典型的启用了Spring Securi ...

  5. gwt格式_使用Spring Security保护GWT应用程序的安全

    gwt格式 在本教程中,我们将看到如何将GWT与Spring的安全模块(即Spring Security)集成. 我们将看到如何保护GWT入口点,如何检索用户的凭据以及如何记录各种身份验证事件. 此外 ...

  6. 使用Spring Security保护GWT应用程序

    在本教程中,我们将看到如何将GWT与Spring的安全模块(即Spring Security)集成在一起. 我们将看到如何保护GWT入口点,如何检索用户的凭据以及如何记录各种身份验证事件. 此外,我们 ...

  7. 使用带有OAuth的Spring Security保护资源

    1.简介 在本教程中,我们将研究如何使用Spring Security和OAuth来基于路径模式( / api / ** )保护服务器上的管理资源. 我们配置的另一个路径模式( / oauth / t ...

  8. Spring Security OAuth2 微服务认证中心自定义授权模式扩展以及常见登录认证场景下的应用实战

    本文源码地址 后端:https://gitee.com/youlaitech/youlai-mall/tree/v2.0.1 前端:https://gitee.com/youlaiorg/mall-a ...

  9. 使用JWT和Spring Security保护REST API

    通常情况下,把API直接暴露出去是风险很大的,不说别的,直接被机器攻击就喝一壶的.那么一般来说,对API要划分出一定的权限级别,然后做一个用户的鉴权,依据鉴权结果给予用户开放对应的API.目前,比较主 ...

最新文章

  1. str.format() 格式化字符串函数
  2. 【Linux】34. shell脚本判断当前年份是否正确
  3. POI导出excel日期格式
  4. JZOJ 5609. 【NOI2018模拟3.28】Tree BZOJ 4919: [Lydsy1706月赛]大根堆
  5. sql server 事务_SQL Server事务概述
  6. html5中本地存储概念是什么?
  7. L1-010 比较大小 (10 分)—团体程序设计天梯赛
  8. Map集合-根据宠物昵称查找宠物
  9. hql中 oracle当前时间,hql oracle 比较 日期时间
  10. matlab高数数学报告,高等数学实验报告matlab参考答案
  11. 如何五分钟实现无线WEP网络入侵(ZZ)
  12. 一个简单的矩阵乘法计算器
  13. B. Remove Prefix
  14. 重磅出炉!KCon 黑客大会 2019 演讲议题正式公布
  15. LSTM之父最新长文:现代AI和深度学习发展史
  16. 宜早不宜晚,使用思维导图训练孩子的逻辑思维!
  17. android------之高德地图实现定位和3D地图显示
  18. 相对分子质量 c编程
  19. how2heap 深入学习(2)
  20. NET:Error Creating Control -Object Reference Not Set To An Instance Of Object

热门文章

  1. arrylist和linked list区别
  2. json vs obj
  3. @ResponseBody导致的返回值中文乱码
  4. 把本地库推送到github远程库
  5. RabbitMQ消息
  6. Hibernate的关联映射--一对多、
  7. easyUI 运用窗口和form表单制作导出功能
  8. jdk12 switch_玩JDK 12的Switch表达式
  9. java cr_WildFly 10 CR 2发布– Java EE 7,Java 8,Hibernate 5,JavaScript支持热重载
  10. hazelcast入门教程_Hazelcast入门指南第4部分