首页 > 解决方案 > 如何使用 JUnit 在 Spring 应用程序中测试安全端点?

问题描述

我在我的 Spring 项目中使用基于 JWT 的身份验证,并且我试图为安全端点编写 JUnit 测试用例,尽管我无法对其进行测试并获得

org.opentest4j.AssertionFailedError:预期:201 实际:403

我的安全配置文件是:

@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class ScopeMapping extends WebSecurityConfigurerAdapter {
    @Autowired
    XsuaaServiceConfiguration xsuaaServiceConfiguration;
    private static final String VT_SCOPE = "VT";
    private static final String DEVELOPER_SCOPE = "Developer";
    private static final String USER_SCOPE = "User";
    private static final String ADMIN_SCOPE = "Admin";
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http
                .headers()
                .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/");
        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .mvcMatchers(HttpMethod.GET,"/health").permitAll()
                .mvcMatchers("/v2/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", "/swagger-resources/**").permitAll()
                .mvcMatchers("/v1/**").hasAuthority(VT_SCOPE)
                .mvcMatchers("/v2/**").permitAll()
                .mvcMatchers("/user/**").hasAnyAuthority(VT_SCOPE, ADMIN_SCOPE, USER_SCOPE, DEVELOPER_SCOPE)
                .mvcMatchers("/admin/**").hasAnyAuthority(VT_SCOPE, ADMIN_SCOPE, DEVELOPER_SCOPE)
                .mvcMatchers("/vt/**").hasAnyAuthority(VT_SCOPE, DEVELOPER_SCOPE)
                .anyRequest().denyAll()
                .and()
                .oauth2ResourceServer()
                .jwt()
                .jwtAuthenticationConverter(getJwtAuthenticationConverter());
    }
    Converter<Jwt, AbstractAuthenticationToken> getJwtAuthenticationConverter() {
        TokenAuthenticationConverter converter = new TokenAuthenticationConverter(xsuaaServiceConfiguration);
        converter.setLocalScopeAsAuthorities(true);
        return converter;
    }
}

测试用例

@WithUserDetails(value="ram",userDetailsServiceBeanName = "secureBean")
    public void addForumTest() throws Exception {
        //  ForumQuery forumQuery = new ForumQuery("1","Query 1","Query 1 Desc","1",currentTime,replies,forumLikes);
        ForumQueryDto forumQueryDto = new ForumQueryDto("1","Query 1","Query 1 Desc",userDto,currentTime,repliesDto);
        Mockito.when(forumService.insertQuery(Mockito.any(ForumQueryDto.class))).thenReturn(forumQueryDto);
        MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/user/forum/add")
                .contentType("application/json")
//                .header(HttpHeaders.AUTHORIZATION,<JWT-TOKEN>)
                .content(objectMapper.writeValueAsString(forumQueryDto)))
                .andReturn();
        MockHttpServletResponse response = result.getResponse();
        assertEquals(HttpStatus.CREATED.value(), response.getStatus());
    }

定制豆

@Bean("secureBean")
    public UserDetailsService userDetailsService() {
        GrantedAuthority authority = new SimpleGrantedAuthority("VT_SCOPE");
        GrantedAuthority authority1 = new SimpleGrantedAuthority("ADMIN_SCOPE");
        GrantedAuthority authority2 = new SimpleGrantedAuthority("USER_SCOPE");
        GrantedAuthority authority3 = new SimpleGrantedAuthority("DEVELOPER_SCOPE");
        UserDetails userDetails = (UserDetails) new User("ram", "ram123", Arrays.asList(authority
                , authority1, authority2, authority3));
        return new InMemoryUserDetailsManager(Arrays.asList(userDetails));
    }

标签: javaspringtestingspring-security

解决方案


请看这里。Spring 安全性带有适当的测试支持。我已经共享了专门用于测试安全性支持的部分的链接。

例子:

@Test
@WithMockUser(username="admin",roles={"USER","ADMIN"})
public void getMessageWithMockUserCustomUser() {
    String message = messageService.getMessage();
    ...
}

这就是您在类上应用测试注释的方式。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WithMockUser(username="admin",roles={"USER","ADMIN"})
public class WithMockUserTests {
}

推荐阅读