当前位置:  开发笔记 > 编程语言 > 正文

在oAuth2资源服务器应用程序中使用@WithMockUser(带有@SpringBootTest)

如何解决《在oAuth2资源服务器应用程序中使用@WithMockUser(带有@SpringBootTest)》经验,为你挑选了1个好方法。

环境:我有一个基于spring boot的微服务架构应用程序,包括多个基础结构服务和资源服务(包含业务逻辑).授权和身份验证由oAuth2-Service处理,管理用户实体并为客户端创建JWT令牌.

为了完整地测试单个微服务应用程序,我尝试使用testNG,spring.boot.test,org.springframework.security.test构建测试...

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, properties = {"spring.cloud.discovery.enabled=false", "spring.cloud.config.enabled=false", "spring.profiles.active=test"})
@AutoConfigureMockMvc
@Test
public class ArtistControllerTest extends AbstractTestNGSpringContextTests {

  @Autowired
  private MockMvc mvc;

  @BeforeClass
  @Transactional
  public void setUp() {
    // nothing to do
  }

  @AfterClass
  @Transactional
  public void tearDown() {
    // nothing to do here
  }

  @Test
  @WithMockUser(authorities = {"READ", "WRITE"})
  public void getAllTest() throws Exception {

    // EXPECT HTTP STATUS 200
    // BUT GET 401
    this.mvc.perform(get("/")
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
  }
}

安全性(资源服务器)配置如下

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

  // get the configured token store
  @Autowired
  TokenStore tokenStore;

  // get the configured token converter
  @Autowired
  JwtAccessTokenConverter tokenConverter;

  /**
   * !!! configuration of springs http security !!!
   */
  @Override
  public void configure(HttpSecurity http) throws Exception {
      http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/**").authenticated();
  }

  /**
   * configuration of springs resource server security
   */
  @Override
  public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    // set the configured tokenStore to this resourceServer
    resources.resourceId("artist").tokenStore(tokenStore);
  }

}

以及基于安全检查的以下方法在控制器类内部进行了注释

@PreAuthorize("hasAuthority('READ')")
@RequestMapping(value = "/", method = RequestMethod.GET)
public List getAll(Principal user) {
    List foos = fooRepository.findAll();
    return foos;
}

我认为这样可行,但在运行测试时我只会收到断言错误

java.lang.AssertionError: Status 
Expected :200
Actual   :401


问题:我做错了吗?或者@WithMockUser是否无法在oAuth2环境中使用@SpringBootTest和@AutoConfigureMockMvc?如果是这种情况......作为这样的(集成)测试的一部分,测试基于路由和方法的安全配置的最佳方法是什么?


附录:我也尝试了不同的方法,如下面的内容......但它导致了相同的结果:(

this.mvc.perform(get("/")
        .with(user("admin").roles("READ","WRITE").authorities(() -> "READ", () -> "WRITE"))
        .accept(MediaType.APPLICATION_JSON))

参见:
spring spring testing
spring boot 1.4测试



1> Jochen Chris..:

@WithMockUserSecurityContext中创建身份验证.同样适用with(user("username")).

默认情况下,OAuth2AuthenticationProcessingFilter不使用SecurityContext,但始终从令牌("无状态")构建身份验证.

您可以轻松更改此行为,将资源服务器安全配置中的无状态标志设置为false:

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration implements ResourceServerConfigurer {

    @Override
    public void configure(ResourceServerSecurityConfigurer security) throws Exception {
        security.stateless(false);
    }

    @Override
    public void configure(HttpSecurity http) {}

}

当然,仅在测试上下文中将标志设置为false.

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有