spring-attic / spring-cloud-security

Security concerns for distributed applications implemented in Spring
Apache License 2.0
532 stars 244 forks source link

a bean of type 'org.springframework.cloud.commons.security.AccessTokenContextRelay' that could not be found. #251

Closed damon008 closed 2 years ago

damon008 commented 2 years ago

Describe the bug Base on

Springboot version:2.5.6
Springcloud version: 2020.0.4
Spring cloud Security version: 2.2.5.RELEASE

I use these, but I found a bug:

Field accessTokenContextRelay in org.springframework.cloud.commons.security.ResourceServerTokenRelayAutoConfiguration$ResourceServerTokenRelayRegistrationAutoConfiguration required a bean of type 'org.springframework.cloud.commons.security.AccessTokenContextRelay' that could not be found.

but I also found the bug on 2.4.x of Springboot and 2020.0.x of spring cloud version.

Sample pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.leinao</groupId>
  <artifactId>test-new</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>test-new</name>
  <url>http://maven.apache.org</url>

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/>
    </parent>

  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <springcloud.version>2020.0.4</springcloud.version>
  </properties>

  <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${springcloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>

        <!-- <dependency>
            <groupId>com.leinao</groupId>
            <artifactId>leinao-commons-core</artifactId>
            <version>0.0.1</version>
        </dependency> -->

        <dependency>
            <groupId>com.leinao</groupId>
            <artifactId>leinao-boot-starter-mybatis</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <!-- <dependency>
             <groupId>org.springframework.security.oauth</groupId>
             <artifactId>spring-security-oauth2</artifactId>
             <version>2.3.8.RELEASE</version>
         </dependency> -->

        <!-- <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
            <optional>true</optional>
        </dependency> -->

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore-nio</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpasyncclient</artifactId>
        </dependency>

        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>

        <!-- <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency> -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator-autoconfigure</artifactId>
        </dependency>

        <!-- <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-kubernetes-fabric8-autoconfig</artifactId>
        </dependency>

        <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-kubernetes-fabric8-config</artifactId>
        </dependency> -->

        <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-kubernetes-fabric8-config</artifactId>
        </dependency>

        <!-- springcloud-k8s-discovery -->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>

        <!-- <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId>
        </dependency> -->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-fabric8-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-fabric8-loadbalancer</artifactId>
        </dependency>

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>

        <!-- springcloud-k8s-discovery end-->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.9.RELEASE</version>
        </dependency>

    </dependencies>
</project>
spencergibb commented 2 years ago

Spring cloud security has migrated to spring cloud gateway (for its part)

damon008 commented 2 years ago

Spring cloud security 已经迁移到spring cloud gateway(就其本身而言)

What? How about Oauth2?

spencergibb commented 2 years ago

spring-security-oauth2 has never been part of Spring cloud

spencergibb commented 2 years ago

The access token relay filter is now part of Spring cloud gateway https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactory.java

damon008 commented 2 years ago

The access token relay filter is now part of Spring cloud gateway https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactory.java

@spencergibb What about clients of oauth2? For example, Resource Server. How to authenticate?

spencergibb commented 2 years ago

Is this what you are looking for https://github.com/spring-cloud/spring-cloud-commons/tree/main/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security

damon008 commented 2 years ago

@spencergibb Base on

Springboot version:2.5.6
Springcloud version: 2020.0.4
Spring cloud Security version: 2.2.5.RELEASE

How can use Oauth2 for Resource Server? for some examples?

Mine:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                "/v2/api-docs", "/swagger-resources/configuration/ui",
                "/swagger-resources","/swagger-resources/configuration/security",
                "/swagger-ui.html","/css/**", "/js/**","/images/**", "/webjars/**", "**/favicon.ico", "/index",
                "/public/", "/static/", "/css/**", "/js/**", "/plugins/**", "/favicon.ico", "/images/**");
    }
}

but it throw a exception:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.cloud.commons.security.ResourceServerTokenRelayAutoConfiguration$ResourceServerTokenRelayRegistrationAutoConfiguration': Unsatisfied dependency expressed through field 'accessTokenContextRelay'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.commons.security.AccessTokenContextRelay' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Description:

Field accessTokenContextRelay in org.springframework.cloud.commons.security.ResourceServerTokenRelayAutoConfiguration$ResourceServerTokenRelayRegistrationAutoConfiguration required a bean of type 'org.springframework.cloud.commons.security.AccessTokenContextRelay' that could not be found.

Action:

Consider defining a bean of type 'org.springframework.cloud.commons.security.AccessTokenContextRelay' in your configuration.
yuanqingfei commented 2 years ago

@damon008 I met exactly the same problem and resolved it. Problem in fact is simple, just because some security code had moved to Spring-cloud-common,so , you have 2 sets currently, you just need exclude old set. Then you will be fine.

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-security</artifactId>
        </exclusion>
    </exclusions>
</dependency>