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

Spring Boot 2.0下用Spring Security OAuth2保护REST API遇问题求助

嘿,我刚好踩过Spring Boot 2.x迁移OAuth2授权服务器配置的坑,给你梳理下核心变化和完整实现方案,帮你搞定这个问题:

在Spring Boot 2.x中用Spring Security OAuth2保护REST API

首先得明确:Spring Boot 2.x对OAuth2的支持做了不少调整,尤其是授权服务器的配置逻辑,和你参考的1.5版本教程差异不小。下面一步步来:

1. 先调整Maven依赖

Spring Boot 2.x不再默认打包OAuth2相关 starter,你需要手动添加依赖。如果是用传统的Spring Security OAuth2模块(注意这个模块现在进入维护状态,后续推荐迁移到官方新的Spring Authorization Server,但针对2.0版本先按传统方案来),POM配置如下:

<dependencies>
    <!-- 基础Web依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Spring Security OAuth2核心依赖 -->
    <dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId>
        <version>2.3.8.RELEASE</version>
    </dependency>
    <!-- Spring Security基础依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
</dependencies>

2. 重写授权服务器配置

你之前用的AuthorizationServerConfigurerAdapter在2.x中还能用,但配置细节有变化,比如密码处理、端点权限等。给你一个完整的配置类示例:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    // 内存存储令牌(测试用,生产建议用JWT或数据库存储)
    private final TokenStore tokenStore = new InMemoryTokenStore();

    // 如果需要密码模式,记得注入AuthenticationManager并在endpoints中配置
    // @Autowired
    // private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        // 允许匿名访问令牌获取端点,允许客户端用表单提交方式拿令牌
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .allowFormAuthenticationForClients();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // 内存存储客户端信息(生产建议存数据库)
        clients.inMemory()
                .withClient("your-client-id")
                .secret("{noop}your-client-secret") // 2.x要求密码必须加密,{noop}表示明文(仅测试)
                .authorizedGrantTypes("password", "refresh_token") // 支持的授权模式:密码、刷新令牌
                .scopes("read", "write") // 权限范围
                .accessTokenValiditySeconds(3600) // 令牌有效期1小时
                .refreshTokenValiditySeconds(86400); // 刷新令牌有效期1天
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore);
        // 密码模式需要添加这一行
        // endpoints.authenticationManager(authenticationManager);
    }
}

3. 配置资源服务器(保护你的API)

接下来要配置资源服务器,指定哪些接口需要OAuth2令牌才能访问:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private static final String RESOURCE_ID = "your-resource-id";

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESOURCE_ID).stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/api/**").authenticated() // 保护/api下所有接口
                .anyRequest().permitAll(); // 其他接口允许匿名访问
    }
}

4. 配置基础Spring Security认证

还需要配置用户信息,这里用内存用户做测试(生产建议用数据库):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // 密码模式需要暴露AuthenticationManager
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("test-user")
                .password("{noop}test-pass")
                .roles("USER");
    }

    // 测试用明文密码编码器,生产必须用BCryptPasswordEncoder!
    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}

核心差异提醒

  • 密码编码强制要求:Spring Boot 2.x默认开启密码加密校验,所以客户端和用户密码要么加{noop}前缀(仅测试),要么用PasswordEncoder加密后存储。
  • 依赖变更:1.5的spring-boot-starter-oauth2在2.x中被拆分,需要手动引入spring-security-oauth2。
  • 后续迁移提示:AuthorizationServerConfigurerAdapter在Spring Security 5.1+被标记为弃用,官方推荐用Spring Authorization Server,但在2.0版本中这个配置完全可用。

测试验证

写个简单的测试接口:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class TestApiController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello from OAuth2 Protected API!";
    }
}

然后用POST请求http://localhost:8080/oauth/token,用form-data传参数:

  • username: test-user
  • password: test-pass
  • grant_type: password
  • client_id: your-client-id
  • client_secret: your-client-secret
    拿到access_token后,请求http://localhost:8080/api/hello,在请求头加Authorization: Bearer {你的access_token},就能正常访问啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:16:11