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

}

ด้วย 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();
    }
}

และการทดสอบบทคัดย่อ:

@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