代码之家  ›  专栏  ›  技术社区  ›  Stephane

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

  •  0
  • Stephane  · 技术社区  · 6 年前

    我正在尝试进行一些集成测试,这些测试使用一些业务控制器,其他测试使用安全配置。

    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);
        }
    
    }
    

    在使用命令运行business controllers测试时 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 回复  |  直到 6 年前