繁体   English   中英

模拟身份验证弹簧安全

[英]mocking authentication spring security

我有一个用@Secured 注释的存储库方法。 我正在尝试为此方法编写单元测试,但我的测试失败了,因为我需要身份验证才能调用该方法。 该方法本身恰好是 save() 方法。 我调用该方法时得到的错误是:

 org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

我无法测试此方法,因为它需要身份验证,而且我无法保存用户进行身份验证(我使用的是 hsqldb),因为我需要调用此方法进行保存。 关于如何对用@secured 注释的方法进行单元测试或如何模拟身份验证的任何建议。

这取决于你想测试什么。

  • 如果您想在没有任何安全性内容的情况下测试应用程序的业务逻辑,您可以完全禁用安全性。 假设您使用SpringJunit4Runner ,您可以将安全配置放入单独的文件中,而不@ContextConfiguration其包含在@ContextConfiguration

  • 如果您想测试授权(例如, @Secured注释的正确工作),您可以直接访问SecurityContext ,绕过所有与身份验证相关的内容(在这种情况下,您可以将身份验证配置放入单独的文件中,并且也不要加载它):

    您只需要将适当的Authentication对象放入SecurityContextHolder

     @Test public void myTest() { login(...); ... logout(); } private void login(...) { SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken(...) ) } private void logout() { SecurityContextHolder.clearContext(); }
  • 最后,如果要测试身份验证,可以使用包含测试数据的数据库运行测试。

a) 这不是单元测试,而是集成测试。 单元测试没有问题。

b) 我会尽量将您的测试设置分开。 为什么不在不测试安全相关功能的测试中停用 spring 安全性?

c) 如果所有其他方法都失败了:在测试设置期间注入JdbcTemplate对象并在 SQL 中手动创建用户数据。 请参阅集成测试的支持类

我会考虑使用诸如@WithMockUser的注释来使用“角色”(具有特定权限的测试用户,如“管理员”、“销售员”等)填充测试安全上下文。

如果@Secured在 repo 上,那一定是因为规范说明了诸如“用户必须拥有此授权才能查询”之类的内容,因此也应该对安全性进行单元测试。

如果UsernameAuthenticationToken@WithMockUser创建的)不能满足您的需求,那么您可以选择其他注释,比如我写的这个,或者甚至自己编写一个创建您想要的确切Authentication实现的注释。

Libs here ,从那里提取的样本结果

@RunWith(SpringRunner.class)
@Import(JwtAuthenticationTokenMessageServiceTests.TestConfig.class)
public class JwtAuthenticationTokenMessageServiceTests {

    @Autowired
    private MessageService<JwtAuthenticationToken> messageService;

    @Test
    @WithMockAuthentication(authType = JwtAuthenticationToken.class, authorities = "ROLE_AUTHORIZED_PERSONNEL")
    public void secretWithScopeAuthorizedPersonnelAuthority() {
        assertThat(messageService.getSecret()).isEqualTo("Secret message");
    }

    @TestConfiguration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @Import({ JwtTestConf.class, JwtAuthenticationTokenServletApp.JwtAuthenticationTokenMessageService.class })
    public static class TestConfig {
    }

暂无
暂无

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

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