Spring @WithMockUser и request.IsUserInRole()

Я использую:

request.IsUserInRole("ADMIN")

в одном из моих контроллеров, чтобы определить ответ на запрос. Я попытался издеваться над запросом в своем тесте, например:

@Mock
private HttpServletRequest httpRequest;

и использовать аннотацию Springs @WithMockUser:

@Test
@WithMockUser(roles={"USER, ADMIN"})
public void getAccountsTest() throws Exception {...}

Оба не работали.

Вопрос 1: Как я могу имитировать request.IsUserInRole("ADMIN") в тесте JUnit?

Вопрос 2: Какое влияние оказывает @WithMockUser на запрос и request.IsUserInRole("ADMIN")?

Спасибо и всего наилучшего

---- редактировать ----

«Не сработало» означает, что у меня есть метод тестирования:

@Test
@WithMockUser(username = "user", roles={"USER"})
public void getAccountsReturnForbiddenTest() throws Exception {
    mockMvc.perform(get("/accounts/"))
        .andExpect(status().isForbidden());
}

который должен возвращать 403, что не разрешено из-за контроллера:

@RequestMapping(method=RequestMethod.GET)
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<PagedResources<AccountResource>> getAccounts(...){...}

Но запрос возвращает 200, ОК.

И я использую Spring Boot 1.4.1.

---- редактировать 2 ----

Мой тестовый класс JUnit:

@Transactional
@ContextConfiguration
public class AccountControllerTestDoc extends AbstractControllerTest {

    @InjectMocks
    private AccountController accountController;

    @Mock
    private AccountService accountService;

    private String uriBase = ""; 

    @Before
    public void setup() {
        // Initialize Mockito annotated components
        MockitoAnnotations.initMocks(this);
        // Prepare the Spring MVC Mock components for standalone testing
        setup(accountController);
    }

    @Test
    @WithMockUser(username = "user", roles={"USER"})
    public void getAccountsReturnForbiddenTest() throws Exception {
        String uri = uriBase + "/accounts";
        mockMvc.perform(get(uri))
            .andExpect(status().isForbidden());
    }

}

с абстрактнымконтроллертестом:

@WebAppConfiguration
public abstract class AbstractControllerTest extends AbstractTest  {

    protected MockMvc mockMvc;

    @Autowired
    protected WebApplicationContext wac;

    protected void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    protected void setup(BaseController controller) {
        mockMvc = MockMvcBuilders.standaloneSetup(controller))
                .build();
    }
}

и абстрактный тест:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public abstract class AbstractTest {

    protected Logger LOG = LoggerFactory.getLogger(this.getClass());

}

---- решение ----

MockMvc standaloneSetup не знает о контексте веб-приложения и, следовательно, не знает о цепочке фильтров безопасности. Необходимо настроить MockMvc с контекстом веб-приложения и цепочкой фильтров безопасности, чтобы иметь возможность тестировать аспекты безопасности.

Вот мое работающее решение, я отредактировал AbstractControllerTest:

@WebAppConfiguration
public abstract class AbstractControllerTest extends AbstractTest  {

    protected MockMvc mockMvc;

    @Autowired
    protected WebApplicationContext wac;

    @Autowired
    FilterChainProxy springSecurityFilterChain;

    protected void setup() {
        mockMvc = MockMvcBuilders
            .webAppContextSetup(wac)
            .addFilters(springSecurityFilterChain)
            .build();
    }

    protected void setup(BaseController controller) {
        mockMvc = MockMvcBuilders.standaloneSetup(controller))
                .build();
    }
}

person user1337    schedule 17.10.2016    source источник
comment
Не работал значит...   -  person chrylis -cautiouslyoptimistic-    schedule 17.10.2016
comment
Извините, не работает означает, что я запускаю запрос на получение защищенного метода без роли администратора, и статус возврата не ожидаемый 403 (не авторизован), а 200 (хорошо).   -  person user1337    schedule 17.10.2016
comment
Пожалуйста, покажите, как вы настраиваете свой mockMvc.   -  person chrylis -cautiouslyoptimistic-    schedule 17.10.2016
comment
У меня был похожий случай, и это сработало для меня stackoverflow.com/a/32777599/4614788   -  person Glenn Van Schil    schedule 15.05.2017


Ответы (1)


Вы должны добавить springSecurityFilterChain при создании MockMvc

protected MockMvc mockMvc;

@Autowired
protected WebApplicationContext wac;

@Autowired
protected Filter springSecurityFilterChain;

protected void setup() {
    mockMvc = MockMvcBuilders
   .webAppContextSetup(wac)
   .addFilters(springSecurityFilterChain)
   .build();
}
person shazin    schedule 17.10.2016
comment
Спасибо за ответ! Немного больше информации об автономной настройке MockMvc из stackoverflow.com/a/34316901/3139759. Я добавил решение в свой начальный сообщение. - person user1337; 17.10.2016