Topik ini menjelaskan konfigurasi terkait beberapa SDK Open Authorization (OAuth) yang umum digunakan, termasuk contoh konfigurasi menggunakan Spring Boot dan OAuth 2.0.
Prasyarat
Aplikasi OAuth telah dibuat. Untuk informasi lebih lanjut, lihat Kelola aplikasi OAuth.
Aplikasi Spring Boot telah dibuat. Untuk informasi lebih lanjut, lihat Spring Boot.
Modifikasi file konfigurasi
Modifikasi file konfigurasi berikut. Untuk informasi lebih lanjut, lihat Spring Boot dan OAuth2.
Buat file konfigurasi inti application.yml atau application.yaml di direktori src/main/resources proyek Spring Boot. Contoh kode berikut memberikan contoh konfigurasi:
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/keysTambahkan dependensi berikut ke file pom.xml:
<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>
Contoh kode lengkap
Kode backend
Sebarkan aplikasi web aman berbasis framework backend Spring Security yang menggabungkan otentikasi, otorisasi, penanganan kesalahan, dan perlindungan terhadap pemalsuan permintaan lintas situs (CSRF). Dalam contoh berikut, RESTful API controller WebApplication didefinisikan. Controller memproses permintaan HTTP dan diintegrasikan dengan sistem otentikasi OAuth 2.0.
Variabel pribadi handler didefinisikan sebagai instance AuthenticationEntryPointFailureHandler dan digunakan untuk menangani kegagalan pada titik masuk otentikasi. Ketika pengguna mencoba mengakses halaman yang memerlukan otentikasi tetapi otentikasi gagal, handler menetapkan kode status HTTP menjadi 401 dan mengembalikan pesan kesalahan "Unauthorized".
Kelas WebApplication menyediakan pemetaan GET ke path
/user. Jika permintaan GET dikirim ke path /user, metode yang ditentukan dalam pemetaan GET dipanggil.Metode tersebut menerima objek OAuth2User sebagai parameter. Objek OAuth2User mewakili informasi OAuth2 dari pengguna yang telah diautentikasi. Kemudian, metode tersebut mengembalikan objek Map yang berisi nama pengguna. Nama pengguna diperoleh dari atribut objek OAuth2User.Dalam metode configure kelas WebApplication, objek HttpSecurity dikonfigurasi untuk mengimplementasikan kebijakan keamanan untuk aplikasi web. Dalam objek HttpSecurity, path yang mengizinkan akses anonim dikonfigurasi, termasuk
/,/error, danwebjars. Dalam objek HttpSecurity, otentikasi identitas untuk permintaan mengakses path lainnya juga dikonfigurasi. Dengan demikian, hanya pengguna yang telah diautentikasi yang dapat mengakses path tersebut.Dalam metode configure, penanganan kesalahan dikonfigurasi. Jika terjadi kesalahan karena pengguna tidak memiliki izin, kode status 401 dikembalikan, dan variabel handler yang telah didefinisikan digunakan untuk menangani kegagalan otentikasi. Dalam metode configure, fitur logon OAuth2 dikonfigurasi untuk menangani kegagalan logon. Jika logon gagal, pesan kesalahan dikonfigurasikan dalam sesi pengguna, dan handler dipanggil untuk menangani kegagalan.
Dalam metode configure, fitur logout dikonfigurasi. Jika pengguna keluar, pengguna dialihkan ke
/. Semua pengguna dapat keluar.Dalam metode configure, perlindungan CSRF dikonfigurasi. CookieCsrfTokenRepository digunakan untuk menyimpan token CSRF, dan atribut HttpOnly dinonaktifkan untuk meningkatkan keamanan. Pemetaan GET tambahan ke metode error dikonfigurasikan untuk menangani permintaan kesalahan. Metode error mendapatkan pesan kesalahan dari sesi pengguna dan menghapus pesan kesalahan sebelum pesan kesalahan dikembalikan. Dengan cara ini, pesan kesalahan tidak ditampilkan berulang kali kepada pengguna.
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; } }
Kode frontend
Buat file index.html di direktori src/main/resources/static proyek untuk verifikasi. Contoh kode berikut memberikan contoh konfigurasi:
<!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">
Dengan Aliyun: <a href="/oauth2/authorization/aliyun">klik di sini</a>
</div>
<div class="container authenticated">
Dengan Google: <a href="/oauth2/authorization/google">klik di sini</a>
</div>
<script type="text/javascript">
$.get("/user", function(data) {
$("#user").html(data.name);
$(".unauthenticated").hide()
$(".authenticated").show()
});
</script>
<div class="container authenticated">
Masuk sebagai:
<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>Verifikasi
Jalankan kode contoh dan akses http://localhost:8080 di browser setelah proyek dimulai.