Spring 在库模块中启动测试 @PreAuthorize

Spring Boot Test @PreAuthorize in a Library Module

我有一个使用 Spring Boot 1.5.21 编写的库模块。

该库有一个 @Service,其中一些方法用 @PreAutorize 注释,只允许具有 ADMIN 权限的用户执行某些操作,例如 删除.

然后我有一个使用该库的 Spring 启动应用程序。如果我 运行 应用程序并手动测试它,它就可以工作。只有管​​理员可以删除。我想为它写测试。

我正在考虑为模块和主应用程序编写单独的测试。在我的模块中,我可以成功地对操作进行单元测试。但是我在测试 @PreAuthotize 时遇到了麻烦,因为安全上下文不存在于模块中,而是存在于主应用程序中。有没有办法在模块中而不是在主应用程序中测试该注释?

我图书馆的相关代码:

@Service
public class MyService {
    @PreAuthorize("hasAuthority('ADMIN')")
    public void delete (long id){
       .....
    }
}
@RunWith(SpringRunner.class)
public class MyServiceTest {

    private MyService service;


    @Test
    @WithAnonymousUser
    public void deleteShouldFailIfAnonymous() {
         ... Verify exception thrown
    }


    @Test
    @WithMockUser(authorities = 'USER')
    public void deleteShouldFailIfNotAdmin() {
         ... Verify exception thrown
    }

    @Test
    @WithMockUser(authorities = 'ADMIN')
    public void deleteShouldPass() {
         ... Should pass
    }
}

我尝试添加 @EnableGlobalMethodSecurity(prePostEnabled = true) 但没有成功。如前所述,SecurityConfiguration 加载到主应用程序中,它不存在于库模块中。

我可以在模块中测试 @PreAuthorize 还是应该将其移至主应用程序?如果可能的话,我想把它放在模块中。或者,也许我可以创建一个仅用于测试的上下文,但不知道该怎么做。

您可以使用MockMvc 进行测试。这将有助于集成测试的模块测试。


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class SecurityTests {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setup() {
        mvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
    }

    @WithMockUser(roles="ADMIN")
    @Test
    public void withMockUser() {
        mvc.perform(get("......"))

    }
}

@PreAuthorize 等面向方面的功能实现为 建议 。通常,这意味着 Spring 将创建一个 decorator interface 拦截方法调用,执行建议(在这种情况下,检查条件并在失败时抛出异常),然后发送调用到服务对象。

当您使用 new MyService 时,您正在创建一个没有实现建议的包装器的裸对象,因此您不会看到应用的安全性、验证、缓存等。要查看您想要的行为,您需要使用 Spring 测试支持来制作测试 bean @Autowired