Backend Development 12 min read

Implementing OAuth2.0 Authorization and Resource Servers with Spring Boot

This article explains OAuth2.0 fundamentals, outlines its roles and grant types, and provides step‑by‑step Spring Boot code to build an authentication server, configure security, set up a resource server, and test the full authorization flow with token handling.

Top Architect
Top Architect
Top Architect
Implementing OAuth2.0 Authorization and Resource Servers with Spring Boot

OAuth 2.0 is an open standard for delegating authorization without sharing user credentials. The article introduces its core concepts, roles (resource owner, client, authorization server, resource server) and four grant types (authorization code, implicit, password, client credentials).

It then shows how to build an authentication center (port 8080) using Spring Boot, adding Maven dependencies for spring-boot-starter-web , spring-cloud-starter-security , and spring-cloud-starter-oauth2 , and provides the MyAuthorizationConfig class that configures token security, client details, token store, and endpoint settings.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-security</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>
</dependencies>
@Configuration
@EnableAuthorizationServer
public class MyAuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    /** 客户端存储策略,这里使用内存方式,后续可以存储在数据库 */
    @Autowired
    private ClientDetailsService clientDetailsService;

    /** Security的认证管理器,密码模式需要用到 */
    @Autowired
    private AuthenticationManager authenticationManager;

    /** 配置令牌访问的安全约束 */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
            .tokenKeyAccess("permitAll()")
            .checkTokenAccess("permitAll()")
            .allowFormAuthenticationForClients();
    }

    /** 配置客户端 */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("test")
            .secret(new BCryptPasswordEncoder().encode("123456"))
            .resourceIds("order")
            .authorizedGrantTypes("authorization_code","password","client_credentials","implicit","refresh_token")
            .scopes("all")
            .autoApprove(false)
            .redirectUris("http://www.baidu.com");
    }

    /** 令牌存储策略 */
    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices services = new DefaultTokenServices();
        services.setClientDetailsService(clientDetailsService);
        services.setSupportRefreshToken(true);
        services.setTokenStore(tokenStore());
        services.setAccessTokenValiditySeconds(60 * 60 * 2);
        services.setRefreshTokenValiditySeconds(60 * 60 * 24 * 3);
        return services;
    }

    @Bean
    public AuthorizationCodeServices authorizationCodeServices() {
        return new InMemoryAuthorizationCodeServices();
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
            .authorizationCodeServices(authorizationCodeServices())
            .authenticationManager(authenticationManager)
            .tokenServices(tokenServices())
            .allowedTokenEndpointRequestMethods(HttpMethod.POST);
    }
}

A SecurityConfig class configures password encoding, enables form‑based login, and defines an in‑memory user for testing.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /** 加密算法 */
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginProcessingUrl("/login")
            .permitAll()
            .and()
            .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password(new BCryptPasswordEncoder().encode("123456"))
            .roles("admin");
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

The resource service (port 8081) is implemented with ResourceServerConfig , which defines a RemoteTokenServices bean pointing to the authentication server’s /oauth/check_token endpoint, sets the client ID/secret, and secures all endpoints to require the "all" scope.

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    /** 配置令牌校验服务 */
    @Bean
    public RemoteTokenServices tokenServices() {
        RemoteTokenServices services = new RemoteTokenServices();
        services.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");
        services.setClientId("test");
        services.setClientSecret("123456");
        return services;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId("order").tokenServices(tokenServices());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/**").access("#oauth2.hasScope('all')")
            .anyRequest().authenticated();
    }
}

Testing steps include requesting an authorization code via http://localhost:8080/oauth/authorize?client_id=test&response_type=code&scope=all&redirect_uri=http://www.baidu.com , logging in with the admin credentials, exchanging the code for an access token, and calling a protected endpoint (e.g., /test ) with and without the token to observe the authorization behavior.

Backend DevelopmentSpring BootAuthenticationinformation securityOAuth2.0
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.