Spring Security Test и MockMvc предоставляют нулевой пользовательский параметр UserDetails контроллеру REST.

Я пытаюсь написать интеграционный тест, который попадает в конечную точку REST и получает данные для конкретного аутентифицированного пользователя (который я настраиваю в тесте). Сначала я попытался настроитьmockMvc = webAppContextSetup(wac).apply(springSecurity()).build(), но это постоянно терпело неудачу сBeanInstantiationException, С помощьюТестирование Spring Security и MvcMock с использованием пользовательской реализации UserDetailsЯ смог преодолеть эту проблему, переключив мою настройку. Теперь, когда я переключил свою настройку на использованиеstandaloneSetupЯ могу позвонить в мой контроллер. Но независимо от того, что я делаю, я не могу получить пользовательский объект UserDetails, который я создаю в своем тесте, в метод в моем контроллере, в котором заканчивается вызов MockMvc.

Я использую Spring 4.2.2 и Spring Security 4.0.1.

Мой тестовый код выглядит примерно так:

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { RestControllerITConfig.class })
@WebAppConfiguration
public class ControllerIT {

  private MockMvc mockMvc;

  @Before
  public void setUp() {
    mockMvc = standaloneSetup(new Controller())
                .setCustomArgumentResolvers(new AuthenticationPrincipalArgumentResolver())
                .build();
  }

  @Test
  public void testGetEndpoint() throws Exception {
    CustomUserDetails userDetails = new CustomUserDetails("John","Smith", "abc123");
    assertNotNull(userDetails);
    MvcResult result = mockMvc.perform(
      get("/somepath").with(user(userDetails)))    
      .andExpect(status().isOk())
      .andExpect(content().contentType("text/json")));
  }
}

@Configuration
@ComponentScan(basePackageClasses = { AuthenticationConfig.class })
public class RestControllerITConfig {
}

@Configuration
@EnableWebSecurity
@ComponentScan("com.my.authentication.package")
public class AuthenticationConfig extends WebSecurityConfigurerAdapter {
  // snip
}

@Target({ ElementType.PARAMETER, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AuthenticationPrincipal
public @interface MyUser {
}

@RestController
@RequestMapping("/somepath")
public class Controller {

  @RequestMapping(value = "", method = RequestMethod.GET)
  public ResponseEntity<Object> getSomePath(@MyUser CustomUserDetails customUser) {
    customUser.getName(); // <== Causes NPE
  }
}

Есть другие части нерелевантной конфигурации, которые были опущены для краткости. Я действительно не понимаю, почему пользовательский объект UserDetails, который я явно создаю в тесте, не передается в мой контроллер REST, а является пустым объектом. Что я здесь не так делаю? У кого-нибудь есть рабочий пример подобного случая? Спасибо заранее.

Ответы на вопрос(1)

Ваш ответ на вопрос