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

前言

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. LeetCode之旅(19)-Power of Two

    题目 Given an integer, write a function to determine if it is a power of two. Credits: Special thanks ...

  2. Android布局优化:include 、merge、ViewStub的详细总结

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 本篇博客主要是对上篇博客的补充Android性能优化之UI渲染性能优化, 没有什么新东西,觉得应该是都掌握的玩意,写出来也只是自己做个小小的总结. ...

  3. nifi1.6.0汉化

    1.1 测试机 l  Apache NiFi 1.6.0 l  HDP 2.6.3 l  集群规模:单节点 l  操作系统:CentOs7 l  以下所有操作均在root用户下执行 1.2 安装环境 ...

  4. JSON 的含义?

    JSON 的全称是 JavaScript Object Notation,是一种轻量级的数据交换格式.JS ON 与 XML 具有相同的特性,例如易于人编写和阅读,易于机器生成和解析.但是 JSON ...

  5. 安装Emacs并设置racket环境

    最近在阅读sicp这本书,书中的代码是使用scheme实现的.之前阅读的时候是使用Dr.Racket来完成写练习的,可我觉得与其这样,不如一步到位,使用emacs+lisp解释器来的比较快. 安装em ...

  6. Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据包访问目标所采取的路径。

    Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据包访问目标所采取的路径.   Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其 ...

  7. 新知识:JQuery语法基础与操作

     jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQuery设计的宗旨是"write ...

  8. 看Instgram课程分享笔记

    第一课:相信直觉.乐于尝试.专注于事而不是陷于创业社交之类的外围活动 第二课:用工程实践解决问题,结交技术朋友 第三课:最难的是找到要解决的问题,用简单方法解决简单问题 第四课:早失败,常失败,由失败 ...

  9. HDU-1017

    A Mathematical Curiosity Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  10. ubuntu16+zabbix3.4+grafana环境搭建记录

    最近研究了zabbix,稍后放上环境搭建教程,建议想学习搭建的同学记得参考zabbix官网