首页 > 解决方案 > 测试期间的 Spring MockMVC、Spring 安全性和全局方法安全性

问题描述

我有以下用户资源,方法createUser被保护到ADMIN角色。

@RestController
@RequestMapping("/api")
public class UserResource {

    @PostMapping("/users")
    @Secured(AuthoritiesConstants.ADMIN)
    public ResponseEntity<User> createUser(@Valid @RequestBody UserDTO userDTO) throws URISyntaxException {
        log.debug("REST request to save User : {}", userDTO);
        // rest of code
    }
}

并在春季启动测试之后

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyappApp.class)
public class UserResourceIntTest {

    // other dependencies

    @Autowired
    FilterChainProxy springSecurityFilterChain;

    private MockMvc restUserMockMvc;

    private User user;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        UserResource userResource = new UserResource(userRepository, userService, mailService);
        this.restUserMockMvc = MockMvcBuilders.standaloneSetup(userResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setMessageConverters(jacksonMessageConverter)
            .apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain))
            .build();
    }



@Test
@Transactional
@WithMockUser(username="user", password = "user", authorities = {"ROLE_USER"})
public void createUser() throws Exception {
    // Create the User
    ManagedUserVM managedUserVM = new ManagedUserVM();
    // set user properties

    restUserMockMvc.perform(post("/api/users")
        .contentType(TestUtil.APPLICATION_JSON_UTF8)
        .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
        .andExpect(status().isCreated());
    }
}

我希望测试失败,因为 api 仅允许ADMIN在 mock 使用USER角色时用于角色,但测试正在通过。任何帮助将不胜感激。

标签: javaspringspring-bootspring-securityjhipster

解决方案


注意:我使用的 JHipster 版本是 5.2.0。不保证这适用于所有版本。

如果您正在使用服务(您应该这样做),您可以注释服务方法。然后在集成测试中使用@WithMockUser应该可以正常工作,而无需进行任何其他更改。这是一个例子。请注意,我还使用了服务接口(在 JDL 中传递“serviceImpl”标志),但它也可以在服务实现中工作。

/**
* Service Interface for managing Profile.
*/
public interface ProfileService {

/**
 * Delete the "id" profile.
 *
 * @param id the id of the entity
 */
@Secured(AuthoritiesConstants.ADMIN)
void delete(Long id);

对应的 rest 控制器方法(由 JHipster 自动生成):

/**
 * DELETE  /profiles/:id : delete the "id" profile.
 *
 * @param id the id of the profileDTO to delete
 * @return the ResponseEntity with status 200 (OK)
 */
@DeleteMapping("/profiles/{id}")
@Timed
public ResponseEntity<Void> deleteProfile(@PathVariable Long id) {
    log.debug("REST request to delete Profile : {}", id);
    profileService.delete(id);
    return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build();
}

推荐阅读