不是因为看到希望了才去坚持,而坚持了才知道没有希望。

前言

Spring Security源码分析十一:Spring Security OAuth2整合JWTSpring Boot 2.0 整合 Spring Security Oauth2中,我们都是使用Restlet Client - REST API Testing测试被Oauth2保护的API。在本章中,我们将展示如何使用MockMvc测试Oauth2API

修改pom.xml

添加spring-security-test依赖

 		<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
</dependency>

修改MerryyouResourceServerConfig配置

   @Override
public void configure(HttpSecurity http) throws Exception { // @formatter:off
http.formLogin()
.successHandler(appLoginInSuccessHandler)//登录成功处理器
.and()
.authorizeRequests()
.antMatchers("/user").hasRole("USER")
.antMatchers("/forbidden").hasRole("ADMIN")
.anyRequest().authenticated().and()
.csrf().disable(); // @formatter:ON
}
  • 修改MerryyouResourceServerConfig配置,增加对指定路径的角色校验。
  • 默认角色为ROLE_USER,详见MyUserDetailsService
@Component
public class MyUserDetailsService implements UserDetailsService { @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return new User(username, "123456", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
}
}

增加/user和/forbidden请求映射

@GetMapping("/user")
public Object getCurrentUser1(Authentication authentication, HttpServletRequest request) throws UnsupportedEncodingException {
log.info("【SecurityOauth2Application】 getCurrentUser1 authenticaiton={}", JsonUtil.toJson(authentication)); String header = request.getHeader("Authorization");
String token = StringUtils.substringAfter(header, "bearer "); Claims claims = Jwts.parser().setSigningKey(oAuth2Properties.getJwtSigningKey().getBytes("UTF-8")).parseClaimsJws(token).getBody();
String blog = (String) claims.get("blog");
log.info("【SecurityOauth2Application】 getCurrentUser1 blog={}", blog); return authentication;
} @GetMapping("/forbidden")
public String getForbidden() {
return "forbidden";
}
  • /user请求需要USER角色
  • /forbidden请求需要ADMIN角色

增加测试类SecurityOauth2Test

@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = SecurityOauth2Application.class)
@Slf4j
public class Oauth2MvcTest { @Autowired
private WebApplicationContext wac; @Autowired
private FilterChainProxy springSecurityFilterChain; private MockMvc mockMvc; //clientId
final static String CLIENT_ID = "merryyou";
//clientSecret
final static String CLIENT_SECRET = "merryyou";
//用户名
final static String USERNAME = "admin";
//密码
final static String PASSWORD = "123456"; private static final String CONTENT_TYPE = "application/json;charset=UTF-8"; @Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilter(springSecurityFilterChain).build();//初始化MockMvc对象,添加Security过滤器链
}
  • 初始化Oauth2信息

obtainAccessToken

  public String obtainAccessToken() throws Exception {
final MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "password");
params.add("client_id", CLIENT_ID);
params.add("username", USERNAME);
params.add("password", PASSWORD); // @formatter:off ResultActions result = mockMvc.perform(post("/oauth/token")
.params(params)
.with(httpBasic(CLIENT_ID, CLIENT_SECRET))
.accept(CONTENT_TYPE))
.andExpect(status().isOk())
.andExpect(content().contentType(CONTENT_TYPE)); // @formatter:on String resultString = result.andReturn().getResponse().getContentAsString(); JacksonJsonParser jsonParser = new JacksonJsonParser();
// System.out.println(jsonParser.parseMap(resultString).get("access_token").toString());
return jsonParser.parseMap(resultString).get("access_token").toString();
}

测试obtainAccessToken

 @Test
public void getAccessToken() throws Exception {
final String accessToken = obtainAccessToken();
log.info("access_token={}", accessToken);
}

控制台打印:

access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE1MjY0NjEwMzgsImJsb2ciOiJodHRwczovL2xvbmdmZWl6aGVuZy5naXRodWIuaW8vIiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6ImE1MmE2NDI4LTcwNzctNDcwZC05M2MwLTc0ZWNlNjFhYTlkMCIsImNsaWVudF9pZCI6Im1lcnJ5eW91In0.CPmkZmfOkgDII29RMIoMO7ufAe5WFrQDB7SaMDKa128

UnauthorizedTest

    /**
* 未授权 401
*
* @throws Exception
*/
@Test
public void UnauthorizedTest() throws Exception {
// mockMvc.perform(get("/user")).andExpect(status().isUnauthorized());
ResultActions actions = mockMvc.perform(get("/user"));
int status = actions.andReturn().getResponse().getStatus();
Assert.assertTrue(status == HttpStatus.UNAUTHORIZED.value());
}
  • 未授权 401

forbiddenTest

   /**
* 禁止访问 403
*
* @throws Exception
*/
@Test
public void forbiddenTest() throws Exception {
final String accessToken = obtainAccessToken();
log.info("access_token={}", accessToken);
mockMvc.perform(get("/forbidden").header("Authorization", "bearer " + accessToken)).andExpect(status().isForbidden());
}
  • 禁止访问 403

accessTokenOk

    /**
* 允许访问 200
*
* @throws Exception
*/
@Test
public void accessTokenOk() throws Exception {
final String accessToken = obtainAccessToken();
log.info("access_token={}", accessToken);
mockMvc.perform(get("/user").header("Authorization", "bearer " + accessToken)).andExpect(status().isOk());
}
  • 允许访问 200

代码下载

推荐文章

  1. Java创建区块链系列
  2. Spring Security源码分析系列
  3. Spring Data Jpa 系列
  4. 【译】数据结构中关于树的一切(java版)
  5. SpringBoot+Docker+Git+Jenkins实现简易的持续集成和持续部署

使用Spring MVC测试Spring Security Oauth2 API的更多相关文章

  1. Spring MVC测试框架

    原文链接:http://jinnianshilongnian.iteye.com/blog/2004660 Spring MVC测试框架详解——服务端测试 博客分类: springmvc杂谈 spri ...

  2. Spring MVC测试框架详解——服务端测试

    随着RESTful Web Service的流行,测试对外的Service是否满足期望也变的必要的.从Spring 3.2开始Spring了Spring Web测试框架,如果版本低于3.2,请使用sp ...

  3. Spring MVC和Spring Boot的理解以及比较

    Spring MVC是什么?(1)Spring MVC是Spring提供的一个强大而灵活的模块式web框架.通过Dispatcher Servlet, ModelAndView 和 View Reso ...

  4. Spring MVC 到 Spring Boot 的简化之路(山东数漫江湖)

    背景 从Servlet技术到Spring和Spring MVC,开发Web应用变得越来越简捷.但是Spring和Spring MVC的众多配置有时却让人望而却步,相信有过Spring MVC开发经验的 ...

  5. 【转】Spring,Spring MVC及Spring Boot区别

    对于一个Java开发者来说,Spring可谓如雷贯耳,无论是Spring框架,还是Spring引领的IOC,AOP风格,都对后续Java开发产生的深远的影响,同时,Spring社区总能及时响应开发者的 ...

  6. Spring MVC 到 Spring BOOT 的简化之路

    背景 Spring vs Spring MVC vs Spring Boot Spring FrameWork Spring 还能解决什么问题 Spring MVC 为什么需要Spring Boot ...

  7. Spring MVC 和 Spring 总结

    1. 为什么使用Spring ? 1). 方便解耦,简化开发 通过Spring提供的IoC容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合. 2). AOP编程的 ...

  8. Spring,Spring MVC及Spring Boot区别

    什么是Spring?它解决了什么问题? 我们说到Spring,一般指代的是Spring Framework,它是一个开源的应用程序框架,提供了一个简易的开发方式,通过这种开发方式,将避免那些可能致使代 ...

  9. spring、spring mvc与spring boot的区别是什么?

    Spring 的功能 Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 ao ...

随机推荐

  1. lambda表达式初步

    // Lambda_test20140801.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <algorithm& ...

  2. Java IO学习--(二)文件

    在Java应用程序中,文件是一种常用的数据源或者存储数据的媒介.所以这一小节将会对Java中文件的使用做一个简短的概述.这篇文章不会对每一个技术细节都做出解释,而是会针对文件存取的方法提供给你一些必要 ...

  3. App 被拒 -- App Store Review Guidelines (2015)中英文对照

    Introduction(简介) We're pleased that you want to invest your talents and time to develop applications ...

  4. poi excel 常用操作

    基本 Workbook wb= new HSSFWorkbook(); Sheet sheet = wb.createSheet("sheetName"); Row row = s ...

  5. Form 和 Input 对象

    更改表单的 action 属性 <html> <head> <script type="text/javascript"> function c ...

  6. Javac的实现过程

    主要介绍Javac的实现过程及原理. 首先弄明白什么是Javac? Javac是一种编译器,将一种语言转换为另一种语言规范.编译器的作用就是将符合java语言规范的源代码转化为JVM虚拟机能够识别的字 ...

  7. Java在线考试系统(含源码)

    本文demo下载和视频教学观看地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1076 本实例介绍了在线考 ...

  8. PHP内核之旅-2.SAPI中的Cli

    PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli 一.SAPI是什么? 1.1 理解SAPI (1)SAPI是PHP框架的接口层.有很多种服务器的SAPI的实 ...

  9. 基于NetMQ的TLS框架NetMQ.Security的实现分析

    基于NetMQ的TLS框架NetMQ.Security的实现分析 前言 介绍 交互过程 支持的协议 TLS协议 支持的算法 实现 握手 第一次握手 Client Hello 第二次握手 Server ...

  10. VueJs(12)---vue-router(导航守卫,路由元信息)

    vue-router(导航守卫,路由元信息) 之前泄露两篇有关vue-router博客: VueJs(10)---vue-router(进阶1) VueJs(11)---vue-router(进阶2) ...