私は非常に単純なREST Spring MVCを使用して作成されたアプリケーションを持っています。(コードは GitHub で入手できます。)単純な WebSecurityConfigurer
次のように:
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers("/user/new").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.and()
.logout()
.permitAll()
.logoutSuccessHandler(logoutSuccessHandler);
}
アプリケーションを実行すると、カスタムコントローラーとログイン/ログアウトページの両方が問題なく機能します。 ユニットテスト/user/new
MockMvc
経由でも可能です。しかし、次の関数で/login
をテストしようとすると
@Test
public void testUserLogin() throws Exception {
RequestBuilder requestBuilder = post("/login")
.param("username", testUser.getUsername())
.param("password", testUser.getPassword());
mockMvc.perform(requestBuilder)
.andDo(print())
.andExpect(status().isOk())
.andExpect(cookie().exists("JSESSIONID"));
}
次のように失敗します。
MockHttpServletRequest:
HTTP Method = POST
Request URI = /login
Parameters = {username=[test-user-UserControllerTest], password=[test-user-UserControllerTest-password]}
Headers = {}
Handler:
Type = org.springframework.web.servlet.resource.ResourceHttpRequestHandler
Async:
Was async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.HttpRequestMethodNotSupportedException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
MockHttpServletResponse:
Status = 405
Error message = Request method 'POST' not supported
Headers = {Allow=[HEAD, GET]}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Java.lang.AssertionError: Status expected:<200> but was:<405>
しかし、私はかなりのユーザーですPOST
から/login
は、テストではなくアプリケーションを実行すると機能します。さらに、(ログのHeaders = {Allow=[HEAD, GET]}
行に示されているように)GET
またはHEAD
リクエストを実行しようとすると、今回は404を受け取ります。で、どうすれば修正できますか?
Githubリンクに気づきました。テストにもセキュリティフィルターを設定する必要があると思います。何かのようなもの
mockMvc = MockMvcBuilders.webApplicationContextSetup(webApplicationContext)
.addFilter(springSecurityFilterChain)
.build();
いくつかの追加設定が必要になる場合があります。インスピレーションを得るために http://www.petrikainulainen.net/programming/spring-framework/integration-testing-of-spring-mvc-applications-security/ を確認してください。
Springセキュリティテストクラスを使用して、フォームベースのログインをテストできます。フォームベースのログインをテストするには、次の手順を実行する必要があります。
Mavenの依存関係:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.0.0.M1</version>
<scope>test</scope>
</dependency>
<repositories>
<repository>
<id>spring-snasphot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
テストクラス:
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
RequestBuilder requestBuilder = formLogin().user("username").password("passowrd");
mockMvc.perform(requestBuilder)
.andDo(print())
.andExpect(status().isOk())
.andExpect(cookie().exists("JSESSIONID"));
SpringSessionをテストして、セッションCookieを取得し、これを実行して組み込みRedisにセッションを保存することを達成しました。
@Autowired
private SessionRepositoryFilter<?> springSessionRepositoryFilter;
...
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSessionRepositoryFilter)
.apply(springSecurity())
.build();
}
それが役に立てば幸い。
ここに私の投稿に従ってください: Spring MockMvcBuildersセキュリティフィルター
REST API with UsernamePasswordAuthenticationToken for/oauth/tokenを作成できましたが、保護されたリソースのテストを作成できませんでした(実行中のサーバーでは正常に動作します)。あなたのRESTインターフェース?