2015-10-05 13 views
8

私は春のブートバージョン "1.3.0.M5"(私もバージョン "1.2.5.RELEASE"を試しました)を使用します。春の起動、テストのセキュリティを無効にする

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.springframework.security</groupId> 
    <artifactId>spring-security-test</artifactId> 
    <scope>test</scope> 
</dependency> 

とコード:

@SpringBootApplication 
public class SpringBootMainApplication { 
    public static void main(String[] args) { 
    SpringApplication.run(SpringBootMainApplication.class, args); 
    } 
} 

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); 
    } 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http.authorizeRequests() 
    .antMatchers("/api/sampleentity").authenticated() 
    .and().authorizeRequests() 
    .and().formLogin().permitAll() 
    .and().logout().permitAll().logoutUrl("/logout") 
    .logoutSuccessUrl("/"); 
    } 
    @Override 
    @Bean 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
    return super.authenticationManagerBean(); 
    } 
} 

@RestController 
@RequestMapping("/api/sampleentity") 
public class SampleEntityController { 
    @RequestMapping(method= RequestMethod.GET) 
    public Iterable<SampleEntity> getAll() { 
    return ImmutableSet.of(); 
    } 
    @RequestMapping(method=RequestMethod.POST) 
    @ResponseStatus(value= HttpStatus.CREATED) 
    public SampleEntity create(@RequestBody SampleEntity sampleEntity) { 
    return sampleEntity; 
    } 
} 

及び/ API/sampleentityがアクセスされたときに失敗してテスト:org.springframework.web.client.HttpClientErrorException:春のセキュリティを加え403は禁止します(.. 。)

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = SpringBootMainApplication.class) 
@WebAppConfiguration 
@IntegrationTest({"server.port=0"}) 
public class SampleEntityTest { 
    @Value("${local.server.port}") 
    private int port; 
    private String url; 
    private RestTemplate restTemplate; 
    @Autowired 
    private ApplicationContext context; 
    @BeforeClass 
    public static void authenticate(){ 
//ONE TRY 
//  Authentication authentication = 
//    new UsernamePasswordAuthenticationToken("user", "password", 
//              AuthorityUtils.createAuthorityList("USER")); //tried "ROLE_USER" 
//  SecurityContextHolder.getContext().setAuthentication(authentication); 
    } 
    @Before 
    public void setUp() { 
    url = String.format("http://localhost:%s/api/sampleentity", port); 
    restTemplate = new RestTemplate(); 
//ANOTHER TRY 
//  AuthenticationManager authenticationManager = context.getBean(AuthenticationManager.class); 
//  Authentication authentication = authenticationManager 
//    .authenticate(new UsernamePasswordAuthenticationToken("user", "password", AuthorityUtils.createAuthorityList("USER"))); //tried "ROLE_USER" 
//  SecurityContextHolder.getContext().setAuthentication(authentication); 
    } 
    //THIS METHOD SHOULD WORK ! 
    @Test 
//ANOTHER TRY 
//@WithMockUser(username="user",password = "password", roles={"USER"})//tried "ROLE_USER" 
    public void testEntity_create() throws Exception { 
    SampleEntity sampleEntity = create("name", 1); 
    ResponseEntity<SampleEntity> response = restTemplate.postForEntity(url, sampleEntity, SampleEntity.class); 
    assertEquals(HttpStatus.CREATED, response.getStatusCode()); 
    } 
    private SampleEntity create(String name, int id) { 
    SampleEntity entity = new SampleEntity(); 
    entity.setName(name); 
    entity.setId(id); 
    return entity; 
    } 
} 

私はメインのアプリケーションを実行する ()とアクセスURL: http://localhost:8080/api/sampleentity 私がログインページにリダイレクトされています。

私のテストを実行し、セキュリティを無効にする方法、または単にユーザーにログインする方法はありますか?

--myソリューション:プロファイルを使用してテストからセキュリティを除外する:

@SpringBootApplication 
@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class}) 
public class SpringBootMainApplication {body the same} 

@EnableWebSecurity 
@Import(SecurityAutoConfiguration.class) 
@Profile("!test") 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {body the same} 

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = SpringBootMainApplication.class) 
@WebAppConfiguration 
@IntegrationTest({"server.port=0"}) 
@ActiveProfiles("test") 
public class SampleEntityTest {body the same} 

答えて

2

をあなたはあなたの問題(複数可)を解決するために、あなたの設定とテストにいくつかの変更を行う必要があります。

まず、あなたのソリューションが動作していない理由を私は説明します:

  1. を春RestTemplateクラスがあなたのRESTサービスにアクセスするための可能な方法であるが、いくつかのヘッダ情報にそれが構築されている方法が欠如している(「doesnのどちらそれはRestTemplateでは不可能です)。認証が機能しなかった理由
  2. RestTemplateリクエストが新しいセッションを作成する可能性があるので、RestTemplateクラスの使用のため、私の最初の解決策の試行は機能しません。全く異なる環境を設定します。 @PreAuthorizeアノテーションで保護されたメソッドをテストする場合は、テストでこのようなメソッドを直接実行し、有効な認証が必要な場合にのみ、自分のコードが機能します。
  3. 現在の春のセキュリティ設定では、どのユーザーも自動的に承認することはできません。

第二に、ここにあなたのコードに必要な変更は以下のとおりです。

私は(HTTPヘッダ属性を経由して認証を有効にする)とI httpBasic認証サポートを追加する必要がありました

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

@Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http.httpBasic().and().csrf().disable() 
    .authorizeRequests().antMatchers("/api/sampleentity").authenticated() 
    .and().authorizeRequests().antMatchers("/users").hasRole("ADMIN") 
    .and().formLogin().permitAll() 
    .and().logout().permitAll().logoutUrl("/logout") 
    .logoutSuccessUrl("/"); 
    } 

    @Override 
    @Bean 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
    return super.authenticationManagerBean(); 
    } 
} 

まず、構成クラス無効にされたcsrfトークン(便宜上、後者はアプリケーションの重要度に応じて有効にする必要があります)。

そして第二にTestClassを:

import java.io.IOException; 
import java.nio.charset.Charset; 
import java.util.Arrays; 

import javax.servlet.Filter; 

import org.junit.Assert; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.test.IntegrationTest; 
import org.springframework.boot.test.SpringApplicationConfiguration; 
import org.springframework.http.MediaType; 
import org.springframework.http.converter.HttpMessageConverter; 
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 
import org.springframework.mock.http.MockHttpOutputMessage; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.web.WebAppConfiguration; 
import org.springframework.test.web.servlet.MockMvc; 
import org.springframework.test.web.servlet.setup.MockMvcBuilders; 
import org.springframework.web.context.WebApplicationContext; 

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; 

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = SpringBootMainApplication.class) 
@WebAppConfiguration 
@IntegrationTest({ "server.port=0" }) 
public class SampleEntityTest { 

private String url; 
private MockMvc mockMvc; 
private HttpMessageConverter mappingJackson2HttpMessageConverter; 

private MediaType contentType = new MediaType(
     MediaType.APPLICATION_JSON.getType(), 
     MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); 

@Autowired 
private WebApplicationContext webApplicationContext; 

@Autowired 
private Filter springSecurityFilterChain; 

@Autowired 
void setConverters(HttpMessageConverter<?>[] converters) { 
    for (HttpMessageConverter hmc : Arrays.asList(converters)) { 
     if (hmc instanceof MappingJackson2HttpMessageConverter) { 
      this.mappingJackson2HttpMessageConverter = hmc; 
     } 
    } 

    Assert.assertNotNull("the JSON message converter must not be null", 
      this.mappingJackson2HttpMessageConverter); 
} 

@Before 
public void setUp() { 
    url = "/api/sampleentity"; 
    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) 
      .addFilters(springSecurityFilterChain).build(); 
} 

@Test 
public void testEntityGet() throws Exception { 
    mockMvc.perform(
      get(url) 
      .with(httpBasic("user", "password"))) 
      .andExpect(status().isOk()); 
} 

@Test 
public void testEntityPost() throws Exception { 
    SampleEntity sampleEntity = new SampleEntity(); 
    sampleEntity.setName("name"); 
    sampleEntity.setId(1); 
    String json = json(sampleEntity); 
    mockMvc.perform(
      post(url) 
      .contentType(contentType) 
      .content(json) 
      .with(httpBasic("user", "password"))) 
      .andExpect(status().isCreated()); 
} 

protected String json(Object o) throws IOException { 
    MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage(); 
    this.mappingJackson2HttpMessageConverter.write(o, 
      MediaType.APPLICATION_JSON, mockHttpOutputMessage); 
    return mockHttpOutputMessage.getBodyAsString(); 
} 

}

私はここに春/春のセキュリティテストのアプローチを使用していました。使用

バージョン:

<parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.2.5.RELEASE</version> 
    </parent> 

    <dependency> 
     <groupId>org.springframework.security</groupId> 
     <artifactId>spring-security-core</artifactId> 
     <version>4.0.2.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.security</groupId> 
     <artifactId>spring-security-web</artifactId> 
     <version>4.0.2.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.security</groupId> 
     <artifactId>spring-security-config</artifactId> 
     <version>4.0.2.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.security</groupId> 
     <artifactId>spring-security-test</artifactId> 
     <version>4.0.2.RELEASE</version> 
     <scope>test</scope> 
    </dependency> 

あなたのREST APIをテストしたい場合、私はあなたにChromeの郵便配達用のプラグインをお勧めすることができます。それが問題をより迅速に特定するのに役立ちます。

私はこれが最終的にあなたの問題を解決するのに役立つことを願っています。

+0

私の投稿を更新しました。私はあなたのアドバイスを試みましたが、私はまだ403禁止されています。何が間違っていますか? –

+0

@WithMockUserなしで試用できますか?また、カスタム実装がある場合は、あなたのAuthenticationProviderを提供できますか? – BeWu

+0

こんにちは、この3つの関係は別々に作られました(私は@WithMockUserにコメントしました)。私はカスタムAuthenticationProviderを使用しません。 –

関連する問題