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

前言

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. iOS中判断照片和相机权限

    1.照片权限判断 在iOS6之后,app中使用照片(即自带相册)需要用户权限验证,所以我们可以做一个权限判断给出友好的提示或者界面效果. 相册判断需要导入 <AssetsLibrary/Asse ...

  2. winform编程设定listview选中行

    在做项目中,需要用到listview显示数据.同时,项目要求,通过检索用户输入的数据,程序通过搜索,确定数据所在的行并通过程序设定为选中状态并高亮显示.同时,正常响应鼠标单击响应的效果,单击时,程序设 ...

  3. android的左右侧滑菜单实现

    最近看了很多app应用都采用的是左右侧滑,比如网易新闻.凡客等 这里也试着写一下侧滑 首先看一下效果 然后给出xml布局代码 <RelativeLayout xmlns:android=&quo ...

  4. PS 图像特效-非线性滤波器

    利用非线性滤波器,使图像的色彩凝块,形成一种近似融化的特效. clc; clear all; addpath('E:\PhotoShop Algortihm\Image Processing\PS A ...

  5. obj-c编程10:Foundation库中类的使用(2)[字符串,数组]

    Foundation库的内容不可谓不多,就算很精简的说篇幅也受不了啊!笨猫一向反对博客文章一下子拖拖拉拉写一大坨!KISS哦!so将上一篇文章再分一篇来说,于是有了这篇,可能还会有(3)哦... 我发 ...

  6. java多继承

    众所周知,java面向对象语言中只有单继承的编程语言,也许你会说,通过实现多个接口这种变通的方式达到多继承的目的.没错,你说的对,不过这并不是本片文章要说到的内容,本文要讲到的内容是java中实实在在 ...

  7. 跨JavaScript对象作用域调用setInterval方法

    跨JavaScript对象作用域调用setInterval方法: var id = window.setInterval(function() {foofunc.call(this);}, 200);

  8. aes加解密 Illegal key size

    做aes加密时,发生一个奇怪的错误,在本地环境是好的,发布到测试环境就出问题, java.security.InvalidKeyException: Illegal key size 想到本地环境之前 ...

  9. CoolBlog开发笔记第5课:请求与响应

    教程目录 1.1 CoolBlog开发笔记第1课:项目分析 1.2 CoolBlog开发笔记第2课:搭建开发环境 1.3 CoolBlog开发笔记第3课:创建Django应用 1.4 CoolBlog ...

  10. Ajax的简单使用

    仅介绍Ajax的使用,让入门小白快速上手 //请自行引入jQuery库文件 <script type="text/javascript"> $(function() { ...