美文网首页
使用Spring MVC测试Spring Security Oa

使用Spring MVC测试Spring Security Oa

作者: 淡淡的伤你 | 来源:发表于2018-05-16 15:22 被阅读228次

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

    https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/spring-security-OAuth206.png

    前言

    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实现简易的持续集成和持续部署

    https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/wechat/xiaochengxu.png

    🙂🙂🙂关注微信小程序java架构师历程
    上下班的路上无聊吗?还在看小说、新闻吗?不知道怎样提高自己的技术吗?来吧这里有你需要的java架构文章,1.5w+的java工程师都在看,你还在等什么?

    相关文章

      网友评论

          本文标题:使用Spring MVC测试Spring Security Oa

          本文链接:https://www.haomeiwen.com/subject/dwwpdftx.html