2017-01-24 119 views
0

我们有一个应用程序使用spring-boot-security并配置为使用ssl。如何测试弹簧引导安全ssl控制器

下面

是我的安全配置

@Override 
    protected void configure(HttpSecurity http) throws Exception 
    { 
     // @formatter:off 
     http 
      .authorizeRequests() 
       .antMatchers("/css/**").permitAll() 
       .anyRequest().fullyAuthenticated() 
      .and() 
      .formLogin() 
       .loginPage("/login") 
       .failureUrl("/login?error").permitAll() 
      .and() 
       .logout() 
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 
      .and() 
       .exceptionHandling().accessDeniedPage("/access?error"); 
     // @formatter:on 
    } 

@Override 
public void configure(AuthenticationManagerBuilder auth) throws Exception 
{ 
    auth.inMemoryAuthentication().withUser("admin").password("admin") 
      .roles("ADMIN", "USER", "ACTUATOR").and().withUser("user") 
      .password("user").roles("USER"); 
} 

我们有一个方法级别的安全控制与下面的代码

@GetMapping("/") 
@Secured("ROLE_ADMIN") 
public String home(Map<String, Object> model) 
{ 
    model.put("message", "Hello World"); 
    model.put("title", "Hello Home"); 
    model.put("date", new Date()); 
    return "home"; 
} 

现在,我们希望使用@WebMvcTest注释所以先写Junit的情况下控制器I想要登录然后检查映射/

我已经写了JUNIT测试用例为

@RunWith(SpringRunner.class) 
@WebMvcTest(controllers = HomeController.class, secure = true) 
public class HomeControllerTest 
{ 
    @Autowired 
    private WebApplicationContext context; 

    private MockMvc mvc; 

    @Before 
    public void setup() 
    { 
     mvc = MockMvcBuilders.webAppContextSetup(context) 
       .apply(springSecurity()).build(); 
    } 

    @Test 
    // @WithMockUser(authorities = "ADMIN") 
    public void testHome() throws Exception 
    { 
     /* 
     * TestSecurityContextHolder.getContext().setAuthentication(new 
     * UsernamePasswordAuthenticationToken("admin", "admin", AuthorityUtils 
     * .commaSeparatedStringToAuthorityList("ROLE_ADMIN"))); 
     */ 
     this.mvc.perform(formLogin("/login").user("u", "admin").password("p", "admin")) 
       /* 
       * get("/").with(user("admin").password("pass").roles("USER", 
       * "ADMIN")) .accept(MediaType.APPLICATION_JSON_UTF8)) 
       */ 
       .andExpect(authenticated()).andDo(print()); 
    } 

} 

如何确保我的JUNIT按预期工作。下面是我的print()方法日志。我看到那个端口不见了,该如何设置?该项目的

MockHttpServletRequest: 
     HTTP Method = POST 
     Request URI = /login 
     Parameters = {u=[admin], p=[admin], _csrf=[3f104e63-4a77-487c-9d1c-8b7cf2c2cead]} 
      Headers = {Accept=[application/x-www-form-urlencoded]} 

Handler: 
      Type = null 

Async: 
    Async started = false 
    Async result = null 

Resolved Exception: 
      Type = null 

ModelAndView: 
     View name = null 
      View = null 
      Model = null 

FlashMap: 
     Attributes = null 

MockHttpServletResponse: 
      Status = 302 
    Error message = null 
      Headers = {Location=[https://localhost/login]} 
    Content type = null 
      Body = 
    Forwarded URL = null 
    Redirected URL = https://localhost/login 
      Cookies = [] 

代码库可以在github

回答

0

发现对于初学者来说,配置基于表单的登录时(例如,通过将其设定“/”),你应该设置defaultSuccessUrl()。然后,用户将在尝试成功登录后重定向。

配置完成后,测试用例会更容易。

您可以通过使用.andExpect(redirectedUrl("/"))首先测试成功登录重定向到主页(“/”)。这应该是一种测试方法。

在用@WithMockUser(roles = "ADMIN")注释的第二种测试方法中,您可以验证是否允许ADMIN访问主页(“/”)。

关于端口号,如果你确定你真的需要设置一个自定义端口,你应该能够注册自定义SpringBootMockMvcBuilderCustomizer作为ApplicationContext一个bean,并用它来设定可指定您的自定义端口的默认请求。

问候,

山姆