栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java > SpringBoot

使用Spring MVC测试Spring Security Oauth2 API

SpringBoot 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Spring MVC测试Spring Security Oauth2 API

前言

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

修改pom.xml

添加spring-security-test依赖

 		
			org.springframework.security
			spring-security-test
		
修改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

@Componentpublic class MyUserDetailsService implements UserDetailsService {    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        return new User(username, "123456", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
    }
}
  • 关于为何是hasRole("USER")而不是hasRole("ROLE_USER")请参考:Spring Security源码分析十三:Spring Security 基于表达式的权限控制

  • @formatter:off和@formatter:ON此段代码不进行格式化

增加/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)@Slf4jpublic 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 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
    
    @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
   
    @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
    
    @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

作者:郑龙飞

来源:https://my.oschina.net/merryyou/blog/1813546

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/235527.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号