简体   繁体   English

测试期间的 Spring MockMVC、Spring 安全性和全局方法安全性

[英]Spring MockMVC, Spring security and Global Method Security during test

I have following user resource, method createUser is secured to ADMIN role.我有以下用户资源,方法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
    }
}

And following spring boot test并在春季启动测试之后

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

I expect the test to fail because api is only allowed for ADMIN role while mock is using USER role, but test is passing.我希望测试失败,因为当模拟使用USER角色时,api 只允许用于ADMIN角色,但测试正在通过。 Any help will be really appreciated.任何帮助将不胜感激。

Note: The JHipster version I'm using is 5.2.0.注意:我使用的 JHipster 版本是 5.2.0。 No guarantees that this will work for all versions.不保证这适用于所有版本。

If you are using a service (which you should), you can annotate the service method.如果您正在使用服务(您应该这样做),您可以注释服务方法。 Using @WithMockUser in the integration test should then just work without having to make any other changes. @WithMockUser在集成测试中使用@WithMockUser应该可以正常工作,而无需进行任何其他更改。 Here's an example.这是一个例子。 Note that I'm also using a service interface (pass the "serviceImpl" flag in JDL), but it will work in the service implementation as well.请注意,我还使用了服务接口(在 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);

The corresponding rest controller method (auto-generated by JHipster):相应的休息控制器方法(由 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();
}

JHipster uses MockMvcBuilders.standaloneSetup that get passed a controller instantiated manually (not with Spring and therefore not with AOP). JHipster 使用MockMvcBuilders.standaloneSetup传递手动实例化的控制器(不是使用 Spring,因此不是使用 AOP)。 Therefore the PreAuthorize is not intercepted and security check is skipped.因此不会拦截 PreAuthorize 并跳过安全检查。 You can therefore either @Autowire your controller and pass it to MockMvcBuilders.standaloneSetup which kind of defies the purpose of usesing standalone setup or simply use a WebApplicationContext: MockMvcBuilders.webAppContextSetup with and autowired WepAppContext.因此,您可以 @Autowire 您的控制器并将其传递给MockMvcBuilders.standaloneSetup ,这违背了使用独立设置的目的,或者只是使用 WebApplicationContext: MockMvcBuilders.webAppContextSetup和自动装配的 WepAppContext。

Try removing @WithMockUser annotation and change the test method as below尝试删除@WithMockUser 注释并更改测试方法如下

ManagedUserVM managedUserVM = new ManagedUserVM();
    managedUserVM.setLogin(DEFAULT_LOGIN);
    managedUserVM.setPassword(DEFAULT_PASSWORD);
   managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));

For complete test.为了完整的测试。 You can refer to this.你可以参考这个。

Test Class 测试班

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM