Поддельный аргумент @AuthenticationPrincipal

У меня есть приложение spring-security-oauth2, которое является ResourceServer. У нас есть собственный класс PrincipalExtractor, который создает собственный объект Principal. Этот настраиваемый объект-участник не расширяет Principal или UserDetails

class CustomUser{
//some custom fields
}

class CustomPrincipalExtractor implements PrincipalExtractor{
  @Override 
  public CustomUser extractPrincipal(Map<String, Object> map){
    return new CustomUser(map);
  }
}


class SomeController{
  @GetMapping
  public ResponseEntity(@AuthenticationPrincipal CustomUser user){
     //able to get user object 
  }
}

Приведенный выше код работает нормально. Теперь я хочу протестировать контроллер, но не могу передать экземпляр CustomUser.

@SpringBootTest
@AutoConfigureMockMvc
public class SomeControllerTest{
   @Autowired
   private MockMvc mockMvc;

  @Test
  public void test(){
    mockMvc.perform(get(...).principal(CANNOT pass CustomUser as it does not implement Principal))
  }
}

Я просмотрел некоторые другие решения, которые запрашивают пользовательский HandlerMethodArgumentResolver, но не уверен, как настроить автоконфигурированный MockMvc


person sidgate    schedule 05.09.2018    source источник


Ответы (1)


Мне пришлось применить обходной путь, чтобы получить эту работу.

Создан фиктивный фильтр, который устанавливает объект аутентификации в SecurityContext. Ниже приведен код

public class MockSpringSecurityFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) {}

  @Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    SecurityContextHolder.getContext()
      .setAuthentication((Authentication) ((HttpServletRequest) req).getUserPrincipal());
    chain.doFilter(req, res);
  }

  @Override
  public void destroy() {
    SecurityContextHolder.clearContext();
  }
}

В рамках теста

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

@Test
  public void test(){
    mockMvc.perform(get(...)
     .principal(new UsernamePasswordAuthenticationToken(new CustomUser(), null))...
  }
person sidgate    schedule 25.10.2018
comment
Какое определение для springSecurity()? - person Klesun; 10.02.2020
comment
Нашел - org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers#springSecurity() - person Klesun; 10.02.2020