【问题标题】:Spring Boot, how to pass AuthenticationPrinciple to controller from a test?Spring Boot,如何将身份验证主体从测试传递给控制器​​?
【发布时间】:2019-07-22 12:09:41
【问题描述】:

我有一个 Spring Boot 2 网络服务。它接受 Bearer 令牌并使用 Spring OAuth2 转到外部 URL 并使用该令牌获取用户详细信息。我正在尝试创建测试来测试 Web 服务的实现,但我正在努力弄清楚如何从测试中通过 AuthenticationPrinicple?

这是我的控制器中的方法示例;

@RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity listUserUploadedFiles(@AuthenticationPrincipal Client client) {
        FileListResponse rsp = new FileListResponse(fileStorageService.getUserFiles(client.getUid()));

        return rsp.response(HttpStatus.OK);
    }

这是我目前的测试;

@Test
    public void TestSimple() throws Exception {
        mockMvc.perform(get("/file"))
                .andExpect(status().isOk());
    }

目前测试失败,因为客户端(AuthenticationPrinicple)为空。

我该怎么做?

---- 更新----

这是我的 Client 对象,如您所见,它没有继承 UserDetails。

public class Client implements Serializable {

    private static final long serialVersionUID = 1L;

    private String uid;
    private String email;

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

还有一个 PrincipalExtractor bean 设置。

@Bean
    public PrincipalExtractor principalExtractor() {
        return map -> {
            Client client = new Client();
            client.setUid(String.valueOf(map.get("uid")));
            client.setEmail(String.valueOf(map.get("name")));

            return client;
        };
    }

提供有关该项目的更多信息。这是一个微服务,用户通过在该服务外部发生的 Web 应用程序进行身份验证。当调用此服务器时,会提供一个令牌,该令牌通过身份验证服务器(同样,外部)进行验证。来自身份验证服务器的响应为我们提供了一个 uuid 和一个电子邮件字段,PrincipalExtractor 将它们映射到一个 Client 对象,然后将其传递给要使用的控制器。

【问题讨论】:

标签: spring-boot


【解决方案1】:

您可以在测试@WithMockUser 时模拟您的用户。

如果您使用 MockMvc,则无需额外的 sec-config

 @RunWith(SpringRunner.class)
 @WebMvcTest(SecuredController.class)
 public class SecuredControllerWebMvcIntegrationTest {

     @Autowired
     private MockMvc mockMvc;

     @Test
     @WithMockUser(value = "user")
     public void testSimple() throws Exception {
             mockMvc.perform(get("/file"))
                 ...

如果你想在@SpringBootTest 中使用@WithMockUser,你需要额外的配置

 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
 public class SecuredControllerSpringBootIntegrationTest
      ...
      @Autowired
      private WebApplicationContext context;

       private MockMvc mvc;

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

参考spring-security-integration-tests

【讨论】:

  • 我试过了,但遗憾的是我的原则(客户端)没有扩展 UserDetails。如果有帮助,我已将我的 Client 对象添加到我的原始问题中。我需要以某种方式将 Client 的实例映射到原则。
猜你喜欢
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多