为某些特定测试加载安全性

时间:2018-08-13 22:46:12

标签: spring-security

我正在尝试进行一些用于测试某些业务控制器的集成测试,以及其他用于进行安全配置的测试。

因此,我有业务控制器测试扩展了BaseTest类,而安全配置测试扩展了SecurityBaseTest类。

我只想为执行安全性测试的测试加载安全配置,而不要为业务控制者的测试加载安全性配置,因为这些测试仅应执行控制器而不是安全性配置。

@SpringBootTest(classes = { TestConfiguration.class, WebConfiguration.class })
@RunWith(SpringRunner.class)
public abstract class BaseTest {

    @Before
    public void setup() throws Exception {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).addFilters(springSecurityFilterChain).build();
        httpHeaders = new HttpHeaders();
    }

}

@SpringBootTest(classes = { TestConfiguration.class, SecurityConfiguration.class, WebConfiguration.class })
public abstract class SecurityBaseTest extends BaseTest {

    @Before
    public void setup() throws Exception {
        super.setup();
        userFixtureService.addUserFixture();

        addTokenToRequestHeader(httpHeaders, UserFixtureService.USER_EMAIL);
    }

    private void addTokenToRequestHeader(HttpHeaders headers, String username) {
        tokenAuthenticationService.addTokenToResponseHeader(headers, username);
    }

}

使用命令mvn clean install -Denv="test" -Ddb="h2" -Dtest=UserControllerTest -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 -Xnoagent -Djava.compiler=NONE"运行业务控制器测试时,调试器将显示该安全配置没有正确加载。

但是testCrudOperations方法失败,因为它返回403状态,而不是预期的201状态。并且调试器显示UserController控制器端点根本没有被命中。

public class UserControllerTest extends BaseTest {
    @Test
    public void testCrudOperations() throws Exception {
        MvcResult mvcResult = this.mockMvc
                .perform(post(RESTConstants.SLASH + UserDomainConstants.USERS)
                .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
                .headers(httpHeaders)
                .content(jacksonObjectMapper.writeValueAsString(userResource0)))
                .andExpect(status().isCreated())
                .andExpect(jsonPath("$.firstname").exists())
                .andExpect(jsonPath("$.firstname").value(userResource0.getFirstname()))
                .andExpect(jsonPath("$.lastname").value(userResource0.getLastname()))
                .andExpect(jsonPath("$.email").value(userResource0.getEmail()))
                .andExpect(header().string("Location", Matchers.containsString("/users/"))).andReturn();
        UserResource retrievedUserResource = deserializeResource(mvcResult, UserResource.class);
        assertThatUserResource(retrievedUserResource).hasEmail(userResource0.getEmail());
        assertThatUserResource(retrievedUserResource)
                .hasRole(retrievedUserResource.getUserRoles().iterator().next().getRole());
        userResource0.setResourceId(retrievedUserResource.getResourceId());
    }
}

使用命令mvn clean install -Denv="test" -Ddb="h2" -Dtest=UserAuthenticationTest -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 -Xnoagent -Djava.compiler=NONE"运行安全配置测试时,调试器将显示安全配置已正确加载。

但是testUnsecuredResourceGrantsAccess方法失败,并显示错误No qualifying bean of type 'org.springframework.security.web.FilterChainProxy' available消息。

public class UserAuthenticationTest extends SecurityBaseTest {
    @Test
    public void testUnsecuredResourceGrantsAccess() throws Exception {
            this.mockMvc.perform(
                post(RESTConstants.SLASH + UserDomainConstants.USERS + RESTConstants.SLASH + UserDomainConstants.LOGIN)
                .accept(MediaType.APPLICATION_JSON)
            )
            .andDo(print())
            .andExpect(status().isBadRequest())
            .andReturn();
    }
}

安全配置为:

@EnableWebSecurity(debug = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    public AuthenticationFromCredentialsFilter authenticationFromCredentialsFilter() throws Exception {
        AuthenticationFromCredentialsFilter authenticationFromCredentialsFilter = new AuthenticationFromCredentialsFilter(new AntPathRequestMatcher("/users/login", RequestMethod.POST.name()));
        authenticationFromCredentialsFilter.setAuthenticationManager(authenticationManagerBean());
        return authenticationFromCredentialsFilter;
    }

    @Bean
    public AuthenticationFromTokenFilter authenticationFromTokenFilter() throws Exception {
        AuthenticationFromTokenFilter authenticationFromTokenFilter = new AuthenticationFromTokenFilter(new NegatedRequestMatcher(new AntPathRequestMatcher("/users/login")));
        authenticationFromTokenFilter.setAuthenticationManager(authenticationManagerBean());
        return authenticationFromTokenFilter;
    }

    @Bean
    FilterRegistrationBean<AuthenticationFromTokenFilter> disableAutoRegistration(final AuthenticationFromTokenFilter filter) {
        final FilterRegistrationBean<AuthenticationFromTokenFilter> registration = new FilterRegistrationBean<AuthenticationFromTokenFilter>(filter);
        registration.setEnabled(false);
        return registration;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors();

        http
        .csrf().disable()
        .formLogin().disable()
        .httpBasic().disable()
        .logout().disable();

        http.exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint);

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(simpleCORSFilter, ChannelProcessingFilter.class);

        http
        .addFilterBefore(authenticationFromTokenFilter, UsernamePasswordAuthenticationFilter.class)
        .authorizeRequests()
        .antMatchers("/", "/error").permitAll()
        .antMatchers("/users/login").permitAll()
        .antMatchers("/admin/**").hasRole(UserDomainConstants.ROLE_ADMIN)
        .anyRequest().authenticated();
    }
}

0 个答案:

没有答案