Autentikasi dan Otorisasi
Konfigurasikan autentikasi pengguna menggunakan basis data dan tentukan aturan kendali akses untuk berbagai peran dan jalur.
Autentikasi dan Otorisasi adalah pelajaran Spring Boot 4 Complete Guide gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Spring Boot 4 Complete Guide, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Spring Boot 4 Complete Guide mencakup 4 pelajaran total.
Bagian dari pelajaran ini belum diterjemahkan dan ditampilkan dalam bahasa Inggris.
AuthN vs. AuthZ
In security, we often talk about two key concepts: Authentication and Authorization.
- Authentication (AuthN) is about verifying who you are. Think of it like showing your ID to prove your identity.
- Authorization (AuthZ) is about determining what you are allowed to do once your identity is confirmed. This is like your ID granting you access to certain areas.
Database Auth Flow
Spring Security can use user details stored in a database to authenticate users. Instead of hardcoding users, we can connect to a real data source.
The process typically involves:
- A user attempts to log in.
- Spring Security fetches user details (username, password, roles) from your database.
- It verifies the password.
- If successful, the user is authenticated.
Fetching User Details
The core interface for retrieving user-specific data in Spring Security is UserDetailsService. You'll implement this to tell Spring how to find users in your database.
It has one method: loadUserByUsername(String username). This method returns a UserDetails object, which holds the user's username, password, and authorities (roles).
Custom UserDetailsService
Let's create a simple UserDetailsService. For now, we'll simulate fetching users from a list, but in a real app, this would query a database.
Notice we return a User object, which is a common implementation of UserDetails.
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@Service
public class MyUserDetailsService implements UserDetailsService {
private final Map<String, UserDetails> users = new HashMap<>();
public MyUserDetailsService(PasswordEncoder passwordEncoder) {
// Simulate users from a database
users.put("user", User.builder()
.username("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build());
users.put("admin", User.builder()
.username("admin")
.password(passwordEncoder.encode("adminpass"))
.roles("ADMIN", "USER")
.build());
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = users.get(username);
if (user == null) {
throw new UsernameNotFoundException("User not found: " + username);
}
return user;
}
}Securing Passwords
Storing passwords as plain text is a major security risk. Spring Security requires you to use a PasswordEncoder to securely hash (encode) passwords.
The most common implementation is BCryptPasswordEncoder, which uses a strong hashing algorithm. You'll define this as a Spring bean.
Wiring Up Authentication
Now, let's wire our UserDetailsService and PasswordEncoder into Spring Security's configuration. We'll define a SecurityFilterChain bean.
This filter chain tells Spring how to handle requests, including authentication.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final UserDetailsService userDetailsService;
public SecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) // Disable CSRF for simplicity in this example
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated() // All other requests require authentication
)
.formLogin(form -> form.permitAll()); // Enable form login for browser access
return http.build();
}
}Full Auth Demo
Here's a complete Spring Boot application demonstrating basic authentication using our custom UserDetailsService and PasswordEncoder. Try accessing /hello after logging in!
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class AuthApp {
public static void main(String[] args) {
SpringApplication.run(AuthApp.class, args);
}
}
@RestController
class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, authenticated user!";
}
}
@Service
class MyUserDetailsService implements UserDetailsService {
private final Map<String, UserDetails> users = new HashMap<>();
public MyUserDetailsService(PasswordEncoder passwordEncoder) {
users.put("user", User.builder()
.username("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build());
users.put("admin", User.builder()
.username("admin")
.password(passwordEncoder.encode("adminpass"))
.roles("ADMIN", "USER")
.build());
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = users.get(username);
if (user == null) {
throw new UsernameNotFoundException("User not found: " + username);
}
return user;
}
}
@Configuration
@EnableWebSecurity
class SecurityConfig {
private final UserDetailsService userDetailsService;
public SecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(form -> form.permitAll());
return http.build();
}
}What You Can Do
Once a user is authenticated, authorization determines what resources or actions they are permitted to access. This is done by checking their assigned roles or authorities.
For example, an "ADMIN" user might access admin pages, while a "USER" user can only see their profile.
Securing Paths by Role
Spring Security allows you to define authorization rules directly in your SecurityFilterChain. You can protect specific URL patterns based on roles.
Key methods:
.requestMatchers("/admin/**").hasRole("ADMIN"): Only users with the 'ADMIN' role can access URLs under/admin/..requestMatchers("/user/**").hasAnyRole("USER", "ADMIN"): Users with 'USER' or 'ADMIN' role..anyRequest().authenticated(): All other requests need any authenticated user.
AuthZ in Action
Let's add authorization rules to our previous example. Try logging in as 'user' (password: 'password') and 'admin' (password: 'adminpass') and access the different endpoints.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class AuthZApp {
public static void main(String[] args) {
SpringApplication.run(AuthZApp.class, args);
}
}
@RestController
class SecuredController {
@GetMapping("/public")
public String publicPage() {
return "This is a public page.";
}
@GetMapping("/user/profile")
public String userProfile() {
return "Welcome, user! This is your profile.";
}
@GetMapping("/admin/dashboard")
public String adminDashboard() {
return "Welcome, admin! This is the admin dashboard.";
}
}
@Service
class MyUserDetailsService implements UserDetailsService {
private final Map<String, UserDetails> users = new HashMap<>();
public MyUserDetailsService(PasswordEncoder passwordEncoder) {
users.put("user", User.builder()
.username("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build());
users.put("admin", User.builder()
.username("admin")
.password(passwordEncoder.encode("adminpass"))
.roles("ADMIN", "USER")
.build());
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = users.get(username);
if (user == null) {
throw new UsernameNotFoundException("User not found: " + username);
}
return user;
}
}
@Configuration
@EnableWebSecurity
class SecurityConfig {
private final UserDetailsService userDetailsService;
public SecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public").permitAll() // Public access
.requestMatchers("/user/**").hasRole("USER") // Only USER role
.requestMatchers("/admin/**").hasRole("ADMIN") // Only ADMIN role
.anyRequest().authenticated() // All others need authentication
)
.formLogin(form -> form.permitAll());
return http.build();
}
}Quick Check
Review the concepts of authentication and authorization, and the components involved.
Recap & Next Steps
Great job! In this lesson, you learned to:
- Distinguish between Authentication and Authorization.
- Understand how Spring Security uses databases for authentication.
- Implement a custom
UserDetailsServiceto fetch user data. - Use
PasswordEncoderto secure user passwords. - Configure URL-based authorization rules using roles.
Next, you'll explore more advanced security features like JWT-based authentication for stateless APIs!
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Autentikasi dan Otorisasi” gratis?
Ya — teks lengkap “Autentikasi dan Otorisasi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Spring Boot 4 Complete Guide, upgrade ke CoddyKit PRO. Kursus Spring Boot 4 Complete Guide mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Autentikasi dan Otorisasi”?
Konfigurasikan autentikasi pengguna menggunakan basis data dan tentukan aturan kendali akses untuk berbagai peran dan jalur. Kamu berlatih Spring Boot 4 Complete Guide dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Spring Boot 4 Complete Guide?
Tidak diperlukan pengalaman sebelumnya. Spring Boot 4 Complete Guide di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Autentikasi dan Otorisasi” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Spring Boot 4 Complete Guide ini?
Ya. Setiap pelajaran Spring Boot 4 Complete Guide menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Dasar-Dasar Spring Security
- Autentikasi dan Otorisasi
- Keamanan Berbasis JWT
- Integrasi OAuth2 dan Login Sosial