You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring OAuth2中无法注入AuthorizationServerTokenServices的解决求助

问题描述

我想要测试OAuth2授权,参考了相关方案后,尝试在OAuthHelper类中注入AuthorizationServerTokenServices,代码如下:

@Component
public class OAuthHelper {

    @Autowired
    private AuthorizationServerTokenServices tokenServices;

    public RequestPostProcessor addBearerToken(final String username, String... authorities)
    {
        return mockRequest -> {
            OAuth2Request oauth2Request = new OAuth2Request( null, "client-id",
                    null, true, null, null, null, null, null );
            Authentication userauth = new TestingAuthenticationToken( username, null, authorities);
            OAuth2Authentication oauth2auth = new OAuth2Authentication(oauth2Request, userauth);
            OAuth2AccessToken token = tokenServices.createAccessToken(oauth2auth);
            mockRequest.addHeader("Authorization", "Bearer " + token.getValue());
            return mockRequest;
        };
    }
}

但IntelliJ提示无法找到所需Bean:Could not autowire. No beans of 'AuthorizationServerTokenServices' type found.。我已尝试修改Spring版本、实例化DefaultTokenServices和TokenStore,但均未解决问题。

我的pom配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
        <relativePath/>
    </parent>
    <artifactId>OwnerApp</artifactId>
    <version>${parent.version}</version>
    <name>OwnerApp</name>
    <description>OwnerApp</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</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-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>javax.json</groupId>
            <artifactId>javax.json-api</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
        <dependency>
            <groupId>litvinov.al</groupId>
            <artifactId>Domain</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>
</project>
解决方案

1. 修正依赖与授权服务器定位

你当前引入的spring-boot-starter-oauth2-client是OAuth2客户端依赖,而AuthorizationServerTokenServices属于授权服务器组件,Spring Boot默认不会自动创建该Bean。同时建议将spring-security-oauth2版本升级到2.5.x(与Spring Boot 2.7.x兼容),替换pom中的对应依赖:

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

2. 手动注册AuthorizationServerTokenServices Bean

如果不需要完整的授权服务器,仅用于测试场景,可以手动配置DefaultTokenServices实例作为Spring Bean:

@Configuration
public class OAuthTestConfig {

    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        // 测试用内存存储Token
        tokenServices.setTokenStore(new InMemoryTokenStore());
        tokenServices.setSupportRefreshToken(true);
        // 配置客户端详情,需与代码中的client-id对应
        tokenServices.setClientDetailsService(clientDetailsService());
        return tokenServices;
    }

    @Bean
    public ClientDetailsService clientDetailsService() {
        InMemoryClientDetailsService clientService = new InMemoryClientDetailsService();
        ClientDetails client = ClientDetailsBuilder
                .clientId("client-id")
                .secret("{noop}client-secret") // {noop}表示明文密码,仅测试用
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("read", "write")
                .build();
        clientService.addClientDetails(client);
        return clientService;
    }
}

3. 简化测试方案(无需依赖TokenServices)

如果只是为了验证接口的授权逻辑,可以直接构造测试用Bearer Token,跳过授权服务器组件:

public RequestPostProcessor addBearerToken(final String username, String... authorities) {
    return mockRequest -> {
        // 构造模拟JWT Token,仅用于测试
        String token = Jwts.builder()
                .setSubject(username)
                .claim("authorities", Arrays.stream(authorities)
                        .map(SimpleGrantedAuthority::new)
                        .collect(Collectors.toList()))
                .signWith(SignatureAlgorithm.HS256, "test-secret")
                .compact();
        mockRequest.addHeader("Authorization", "Bearer " + token);
        return mockRequest;
    };
}

注意:这种方式需要在测试环境的资源服务器配置中,关闭Token签名验证或者使用对应的密钥。

4. 检查组件扫描范围

确保OAuthHelper和上述配置类都在Spring Boot主类的扫描范围内,若不在,可通过@ComponentScan(basePackages = "com.your.package")手动指定扫描包路径。


内容的提问来源于stack exchange,提问作者qwert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 03:49:53