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.
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><dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency></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_idis required.
<code>localhost:9999/oauth/authorize?client_id=pigx&response_type=code&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_accessis 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).
Java Architecture Diary
Committed to sharing original, high‑quality technical articles; no fluff or promotional content.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.