Information Security 7 min read

How to Build an OAuth2.0 Authorization Server with Spring Cloud

This article explains how to create an open platform using OAuth2.0 authorization code flow, configure Spring Cloud dependencies, set up the authorization and security servers, test the endpoints, and customize the login and confirmation pages, providing complete code examples and diagrams.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
How to Build an OAuth2.0 Authorization Server with Spring Cloud

This article focuses on the technical implementation of an open platform without discussing multi‑dimensional operational concepts.

What is an Open Platform

By exposing API interfaces of your platform products and services, third‑party developers can directly call them, such as WeChat login, QQ login, WeChat Pay, Weibo login, etc., allowing massive data resources to be accumulated and monetized. Most domestic open platforms are built on the OAuth2.0 protocol.

WeChat Open Platform Authorization Flow Diagram

Weibo Open Platform Authorization Flow Diagram

OAuth2.0 Authorization Code Grant

The authorization code grant is the most complete and secure flow, interacting with the service provider's authentication server via the client’s backend to meet most open‑platform authentication needs.

Introduce Relevant Dependencies

<code>&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-oauth2&lt;/artifactId&gt;
&lt;/dependency&gt;

&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-security&lt;/artifactId&gt;
&lt;/dependency&gt;</code>

Configure Authorization Server

Initialize an in‑memory client that supports the authorization code mode.

<code>@Configuration
@AllArgsConstructor
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Override
    @SneakyThrows
    public void configure(ClientDetailsServiceConfigurer clients) {
        clients.inMemory()
                .withClient("pigx") // client_id
                .secret("pigx") // client_secret
                .authorizedGrantTypes("authorization_code") // allowed grant types
                .scopes("app"); // allowed scopes
    }
}</code>

Initial Completion, Test It

Note that the endpoint is

/oauth/authorize

, not

/oauth/token

; only the

client_id

is required.

<code>localhost:9999/oauth/authorize?client_id=pigx&amp;response_type=code&amp;redirect_uri=https://pig4cloud.com</code>

First perform basic login (default user is user , password shown in console).

Authorization confirmation.

Login success returns a code to the callback URL.

Obtain the access token via /oauth/token .

These simple steps complete the authorization flow similar to WeChat or other sites, though the implementation is still rudimentary.

No UI for login; user passwords are not stored in a database.

The authorization confirmation page is unattractive and lacks personalization.

Configure Secure Login

Redirect unauthenticated requests to loginPage .

Define the post‑login processing path, which will be handled by Spring Security.

<code>@Primary
@Order(90)
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
    @Override
    @SneakyThrows
    protected void configure(HttpSecurity http) {
        http.formLogin()
            .loginPage("/token/login")
            .loginProcessingUrl("/token/form")
            .and()
            .authorizeRequests()
            .anyRequest().authenticated();
    }
}</code>

Implement User Loading Rules for Auth Server

<code>@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    endpoints.userDetailsService(pigxUserDetailsService);
}

// Load username and password from data source
public interface UserDetailsService {
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}</code>

Override Existing Authorization Page

The default logic at

/oauth/confirm_access

is redirected to a custom path for personalization.

<code>@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    endpoints.userDetailsService(pigxUserDetailsService)
             .pathMapping("/oauth/confirm_access", "/token/confirm_access");
}</code>

Retrieve the authorization information from the context and pass it to the front end.

<code>@GetMapping("/confirm_access")
public ModelAndView confirm(HttpServletRequest request, HttpSession session, ModelAndView modelAndView) {
    Map<String, Object> scopeList = (Map<String, Object>) request.getAttribute("scopes");
    modelAndView.addObject("scopeList", scopeList.keySet());

    Object auth = session.getAttribute("authorizationRequest");
    if (auth != null) {
        AuthorizationRequest authorizationRequest = (AuthorizationRequest) auth;
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId(authorizationRequest.getClientId());
        modelAndView.addObject("app", clientDetails.getAdditionalInformation());
        modelAndView.addObject("user", SecurityUtils.getUser());
    }
    modelAndView.setViewName("ftl/confirm");
    return modelAndView;
}
</code>

Final Effect

Displaying user avatar and other information looks nice.

Summary

The source code is based on a personal project: a Spring Cloud, OAuth2.0 based Vue front‑back separated development platform (https://gitee.com/log4j/pig).

Backend Developmentinformation securitySpring CloudOAuth2.0authorization-server
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

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.