Spring boot 资源服务器的Spring集成测试(基于Spring-cloud-starter-oauth2)

Spring boot 资源服务器的Spring集成测试(基于Spring-cloud-starter-oauth2),spring-boot,spring-security,oauth-2.0,spring-oauth2,spring-test-mvc,Spring Boot,Spring Security,Oauth 2.0,Spring Oauth2,Spring Test Mvc,我正在为oAuth2资源服务器使用SpringBoot和SpringCloud。以下是配置: pom.xml org.springframework.boot SpringBootStarterWeb org.springframework.boot 弹簧启动安全 org.springframework.security spring安全acl org.springframework.cloud spring-cloud-starter-oauth2 ... org.springframew

我正在为oAuth2资源服务器使用SpringBoot和SpringCloud。以下是配置:

pom.xml


org.springframework.boot
SpringBootStarterWeb
org.springframework.boot
弹簧启动安全
org.springframework.security
spring安全acl
org.springframework.cloud
spring-cloud-starter-oauth2
...
org.springframework.boot
spring启动程序父级
2.3.4.1发布
org.springframework.cloud
spring云依赖关系
Hoxton.SR8
ResourceServerConfig

@配置
@EnableResourceServer
公共类ResourceServerConfig扩展了ResourceServerConfigurerAdapter{
@值(${my app.security.accession})
私人弦乐观众;
@凌驾
public void配置(ResourceServerSecurityConfigure资源){
resources.resourceId(受众);
}
@凌驾
public void configure(HttpSecurity http)引发异常{
http
.cors()和()
.httpBasic().disable()
.formLogin().disable()
.sessionManagement().sessionCreationPolicy(sessionCreationPolicy.STATELESS)和()
.authorizeRequests(授权->授权)
.antMatchers(“/actuator/**”).permitAll()//TODO:为执行器启用基本身份验证
.anyRequest().authenticated()
);
}
@豆子
公共公司配置源公司配置源(){
UrlBasedCorsConfigurationSource=新的UrlBasedCorsConfigurationSource();
CorsConfiguration CorsConfiguration=新的CorsConfiguration()。applyPermitDefaultValues();
corsConfiguration.addAllowedMethod(“补丁”);
source.registerCorsConfiguration(“/**”,公司配置);
返回源;
}
@豆子
公共资源服务器属性资源服务器属性(){
返回新的ResourceServerProperties(null,null);
}
}
OidcJwkTokenStoreConfig

@配置
公共类OidcJwkTokenStoreConfig{
私有最终资源服务器属性资源;
public OidcJwkTokenStoreConfig(ResourceServerProperties资源){
这个资源=资源;
}
@豆子
公共令牌库JWKTokeStore(UserDetailsService UserDetailsService){
DefaultAccessTokenConverter-tokenConverter=新的DefaultAccessTokenConverter();
setUserTokenConverter(新的MvcUserAuthenticationConverter(userDetailsService));
返回新的JWKTokeStore(this.resource.getJwk().getKeySetUri(),tokenConverter);
}
}
自定义用户身份验证转换器

公共类MvcUserAuthenticationConverter实现UserAuthenticationConverter{
私有最终字符串SUB=“SUB”;
私有最终用户详细信息服务用户详细信息服务;
公共MvcUserAuthenticationConverter(UserDetailsService UserDetailsService){
this.userDetailsService=userDetailsService;
}
@凌驾
公共映射convertUserAuthentication(身份验证userAuthentication){
抛出新的UnsupportedOperationException();
}
@凌驾
公共身份验证提取身份验证(映射){
if(地图集装箱箱(SUB)){
对象主体=map.get(SUB);
收集您可以执行以下操作:

  • 覆盖测试的资源服务器配置,并确保在类路径上放置了有效的RSA公钥(例如,
    /src/test/resources
    ):
  • 示例
    application.yml
    内部
    /src/test/resources

    spring:
      security:
        oauth2:
          resourceserver:
            jwt:
              public-key-location: classpath:id_rsa.pub
    
    这应该满足应用程序的启动要求,并且不需要与授权服务器进行任何HTTP通信

  • 接下来,结合使用
    @SpringBootTest
    @AutoConfigureMockMvc
    对模拟Servlet环境进行测试。确保
    spring安全测试
    依赖项可用

  • 摆脱测试中的自定义
    UserDetailsService
    bean,而是依赖于正常的自动配置

  • 现在,您可以使用例如
    @WithMockUser
    在测试时在Spring SecurityContext中提供模拟用户

  • 要在集成测试期间提供真实的承载令牌,可以执行以下操作:

  • 覆盖您的配置以指向假授权服务器(例如,用于启动本地HTTP服务器)
  • 在应用程序请求JWKS的地方,使用授权服务模拟应用程序(充当资源服务器)的初始HTTP通信。在那里,您可以创建内存中的RSA密钥对,并让模拟身份提供程序返回公钥
  • 创建有效的JWT并使用私钥对其进行签名
  • 使用
    WebTestClient
    testrestemplate
    访问已启动的应用程序,并将令牌添加为请求头的一部分(您需要
    @springbootest(webEnvironment=webEnvironment.RANDOM_PORT)

  • 嗯,这在我的情况下不起作用。我提供了一个
    JwkTokenStore
    (见上文)的自定义实例,以便在我的资源服务器中使用自定义
    UserDetailsService
    。您提供的配置是为了spring引导安全。在我的情况下,我使用spring-cloud-starter-oauth2(因此使用了另一个配置)。好像我弄糟了什么…?你能添加你的自定义
    userdetails服务吗?
    ?Spring OAuth2仍然使用Spring Security中的许多基础结构,因此你也可以使用例如
    @WithMockUser
    在安全上下文中硬编码经过身份验证的用户。添加我的自定义userdetails服务。该服务始终返回一个用户(来自数据库)。如果该用户不存在,将创建一个新的用户。@WithMockUser帮助我对经过身份验证的用户进行硬编码。这种方法帮助我获得测试
    spring:
      security:
        oauth2:
          resourceserver:
            jwt:
              public-key-location: classpath:id_rsa.pub