WedX - журнал о программировании и компьютерных науках

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

Я пытаюсь написать интеграционный тест, который достигает конечной точки REST и получает данные для определенного пользователя, прошедшего проверку подлинности (тот, который я настраиваю в тесте). Сначала я попробовал свою настройку с mockMvc = webAppContextSetup(wac).apply(springSecurity()).build(), но это постоянно терпело неудачу с BeanInstantiationException. С помощью тестирования Spring Security и MvcMock с использованием пользовательского Реализация UserDetails, мне удалось решить эту проблему, переключив файл setUp. Теперь, когда я переключил свои настройки на использование 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

Наконец-то я смог заставить это работать, явно добавив фильтр AuthenticationConfig в файл StandaloneMockMvcBuilder. Итак, моя установка теперь выглядит так:

private MockMvc mockMvc;
@Autowired
private MyController controller;
@Autowired
private AuthenticationConfig authConfig;

@Before
public void setUp() {
  mockMvc = standaloneSetup(controller)
              .setCustomArgumentResolvers(new AuthenticationPrincipalArgumentResolver())
              .addFilters(authConfig.getCustomFilter())
              .build();
}
30.10.2015

2

Если вы используете Spring 5 с настраиваемой реализацией сведений о пользователе, вы можете легко использовать аннотацию @WithUserDetails.

Например

@Test
@WithUserDetails
void createInstitution

Подробности можно найти в документации по безопасности Spring Документация по безопасности Spring

01.07.2021
Новые материалы

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


Для любых предложений по сайту: [email protected]