【问题标题】:Spring @WithMockUser and request.IsUserInRole()Spring @WithMockUser 和 request.IsUserInRole()
【发布时间】:2016-10-17 09:25:44
【问题描述】:

我正在使用:

request.IsUserInRole("ADMIN")

在我的一个控制器中确定对请求的响应。我试图在我的测试中模拟请求,例如:

@Mock
private HttpServletRequest httpRequest;

并使用 Springs 注释 @WithMockUser:

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

两者都不起作用。

问题 1:如何在 JUnit 测试中模拟 request.IsUserInRole("ADMIN")

问题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,OK。

我使用的是 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());
    }

}

使用 AbstractControllerTest:

@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();
    }
}

和 AbstractTest:

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

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

}

----解决方案----

MockMvc standaloneSetup 不知道 Web 应用程序上下文,因此不知道安全过滤器链。必须使用 Web 应用程序上下文和安全过滤器链设置 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();
    }
}

【问题讨论】:

  • “没用”的意思是……
  • 对不起,“没用”意味着我在没有管理员角色的安全方法上运行 get 请求,返回状态不是预期的 403(未授权)而是 200(正常) .
  • 请说明您是如何设置mockMvc的。
  • 我有一个类似的案例,这对我有用stackoverflow.com/a/32777599/4614788

标签: java spring spring-mvc mockito


【解决方案1】:

您应该在创建MockMvc 时添加springSecurityFilterChain

protected MockMvc mockMvc;

@Autowired
protected WebApplicationContext wac;

@Autowired
protected Filter springSecurityFilterChain;

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

【讨论】:

猜你喜欢
  • 2019-03-07
  • 2015-07-14
  • 2021-11-09
  • 2013-06-04
  • 2016-08-03
  • 1970-01-01
  • 2018-05-15
  • 2017-04-15
  • 1970-01-01
相关资源
最近更新 更多