Integrate an Alibaba Cloud OAuth 2.0 application with Spring Boot so that users can log on to your web application with their Alibaba Cloud credentials.
Prerequisites
-
You have created an OAuth 2.0 application in the RAM console. For more information, see Manage OAuth applications.
-
You have a Java development environment and a basic Spring Boot application. Spring Boot documentation.
Step 1: Configure Spring Security and OAuth 2.0
Configure your Spring Boot application to use Spring Security with Alibaba Cloud as the OAuth 2.0 provider. Spring Boot and OAuth2.
1. Add Maven dependencies
Add the following dependencies to your pom.xml file.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>js-cookie</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
</dependencies>
2. Configure OAuth 2.0 provider
Create an application.yml file in the src/main/resources directory with the following OAuth 2.0 provider configuration.
Replace client-id and client-secret with your OAuth application credentials.
spring:
security:
oauth2:
client:
registration:
alibabacloud:
client-id: 415195082384692****
client-secret: 6EwN4qutnZuchG6n677Ie33SsjAhwyTpcOMSoIo6v0gqJtw4QcHhERVXfqzc****
client-authentication-method: client_secret_basic
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
client-name: alibabacloud
provider:
alibabacloud:
authorization-uri: https://signin.alibabacloud.com/oauth2/v1/auth
token-uri: https://oauth.alibabacloud.com/v1/token
user-info-uri: https://oauth.alibabacloud.com/v1/userinfo
user-name-attribute: sub
jwk-set-uri: https://oauth.alibabacloud.com/v1/keys
Step 2: Create the web application code
1. Backend security configuration and controller
Create a main application class that configures Spring Security and exposes a REST endpoint for user information.
import org.springframework.boot.SpringApplication;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.AuthenticationEntryPointFailureHandler;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Map;
public class WebApplication extends WebSecurityConfigurerAdapter {
private AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler((request, response, authException) -> response.sendError(401, "Unauthorized"));
@GetMapping("/user")
public Map<String, Object> user(@AuthenticationPrincipal OAuth2User principal) {
return Collections.singletonMap("name", principal.getAttribute("name"));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(a -> a
.antMatchers("/", "/error", "/webjars/**").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(e -> e
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.oauth2Login(o -> o
.failureHandler((request, response, exception) -> {
request.getSession().setAttribute("error.message", exception.getMessage());
handler.onAuthenticationFailure(request, response, exception);
})
)
.logout(l -> l
.logoutSuccessUrl("/").permitAll()
)
.csrf(c -> c
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
}
@GetMapping("/error")
public String error(HttpServletRequest request) {
String message = (String) request.getSession().getAttribute("error.message");
if (message != null) {
request.getSession().removeAttribute("error.message");
}
return message;
}
}
2. Frontend HTML page
Create an index.html file in the src/main/resources/static directory. This page displays the logon link and user information after authentication.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Demo</title>
<meta name="description" content=""/>
<meta name="viewport" content="width=device-width"/>
<base href="/"/>
<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css"/>
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
<script src="/webjars/js-cookie/js.cookie.js">
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (settings.type === 'POST' || settings.type === 'PUT' || settings.type === 'DELETE') {
if (!(/^(http:\/\/|https:\/\/)/.test(settings.url))) {
xhr.setRequestHeader("X-XSRF-TOKEN", Cookies.get('XSRF-TOKEN'));
}
}
}
});
</script>
</head>
<body>
<h1>Demo</h1>
<div class="container text-danger error"></div>
<script>
$.get("/error", function (data) {
if (data) {
$(".error").html(data);
} else {
$(".error").html('');
}
});
</script>
<div class="container unauthenticated">
With Aliyun: <a href="/oauth2/authorization/aliyun">click here</a>
</div>
<div class="container authenticated">
With Google:<a href="/oauth2/authorization/google">click here</a>
</div>
<script type="text/javascript">
$.get("/user", function(data) {
$("#user").html(data.name);
$(".unauthenticated").hide()
$(".authenticated").show()
});
</script>
<div class="container authenticated">
Logged in as: <span id="user"></span>
<div>
<button onClick="logout()" class="btn btn-primary">Logout</button>
</div>
</div>
<script type="text/javascript">
var logout = function() {
$.post("/logout", function() {
$("#user").html('');
$(".unauthenticated").show();
$(".authenticated").hide();
})
return true;
}
</script>
</body>
</html>
Step 3: Run and verify the application
-
Run your Spring Boot application.
-
Open a browser and navigate to
http://localhost:8080. -
Click the "Click here" link. You are redirected to the Alibaba Cloud logon page.
-
Enter your Alibaba Cloud credentials and grant consent if prompted.
-
After successful authentication, you are redirected back to your application, and the page displays your username.