Spring Boot คือ ตอนที่ 10 : การรับรองความถูกต้อง (Authentication) และการอนุญาต (Authorization)

  1. การรับรองความถูกต้อง (Authentication) และการอนุญาต (Authorization) คืออะไร
  2. การตั้งค่า (Setting Up) แอปพลิเคชัน Spring Boot ของเรา
  3. การกำหนดค่า (Configuring) Spring Security
  4. การใช้ (Implementing) บริการรายละเอียดผู้ใช้ที่กำหนดเอง (Custom User Details Service)
  5. การดำเนินการอนุญาต (Authorization)

ในขณะที่การทำเว็บแอปพลิเคชันยังคงพัฒนาอย่างต่อเนื่อง ความปลอดภัยยังคงเป็นประเด็นสำคัญ ในฐานะนักพัฒนา เราต้องมั่นใจว่าการทำแอพของเราปลอดภัยและเชื่อถือได้สำหรับผู้ใช้ทุกคน รากฐานของการรักษาความปลอดภัยเว็บแอปพลิเคชันมักจะเน้นที่องค์ประกอบสำคัญสองส่วน ได้แก่ การพิสูจน์ตัวตนและการให้สิทธิ์ ในบริบทของ Spring Boot ซึ่งเป็นเฟรมเวิร์กที่ได้รับความนิยมในระบบนิเวศของ Java สิ่งนี้มักเกี่ยวข้องกับการใช้ Spring Security

ในบทความนี้ เราจะเจาะลึกวิธีการใช้การรับรองความถูกต้องและการให้สิทธิ์ในการทำแอพ Spring Boot ซึ่งจะแนะนำคุณตลอดการทำเว็บแอปพลิเคชันอย่างง่ายเพื่ออธิบายแนวคิดเหล่านี้ให้ดียิ่งขึ้น

1. การรับรองความถูกต้อง (Authentication) และการอนุญาต (Authorization) คืออะไร

ก่อนที่จะดำดิ่งสู่การนำไปใช้ สิ่งสำคัญคือต้องเข้าใจว่าการรับรองความถูกต้องและการอนุญาตนั้นเกี่ยวข้องกับอะไร

การยืนยันตัวตนคือกระบวนการยืนยันตัวตนของผู้ใช้ อุปกรณ์ หรือระบบ มักจะเกี่ยวข้องกับการตรวจสอบว่าผู้ใช้เป็นคนที่พวกเขาอ้างว่าเป็นจริงๆ หรือไม่ การตรวจสอบสิทธิ์ในเว็บแอปพลิเคชันมักจะเกี่ยวข้องกับการใช้ชื่อผู้ใช้และรหัสผ่าน แม้ว่าอาจมีวิธีการที่ซับซ้อนกว่า เช่น การตรวจสอบสิทธิ์แบบหลายปัจจัย

ในทางกลับกัน การอนุญาตเป็นกระบวนการของการอนุญาตหรือปฏิเสธการเข้าถึงทรัพยากรหรือการอนุญาตเฉพาะภายในแอปพลิเคชันของผู้ใช้ที่ผ่านการพิสูจน์ตัวตนแล้ว เมื่อผู้ใช้ได้รับการพิสูจน์ตัวตนแล้ว ระบบจะใช้การอนุญาตเพื่อกำหนดว่าผู้ใช้สามารถเข้าถึงทรัพยากรใดหรือดำเนินการใดได้บ้าง

2. การตั้งค่า (Setting Up) แอปพลิเคชัน Spring Boot ของเรา

เริ่มต้นการเดินทางของเราด้วยการตั้งค่าแอปพลิเคชัน Spring Boot ใหม่ หากคุณยังไม่ได้ติดตั้ง Spring Boot บนคอมพิวเตอร์ของคุณ คุณอาจใช้เครื่องมือ Spring Initializr ซึ่งเป็นเครื่องมือทำแอพ Spring Boot แบบออนไลน์

เราต้องการการอ้างอิงต่อไปนี้: Spring Web, Spring Security และ Spring Data JPA นอกจากนี้ เลือกตัวเชื่อมต่อฐานข้อมูลที่เหมาะสมโดยขึ้นอยู่กับตัวเลือกของฐานข้อมูลเชิงสัมพันธ์ สำหรับวัตถุประสงค์ของบทความนี้ เราจะใช้ H2 ซึ่งเป็นฐานข้อมูลในหน่วยความจำ

เมื่อตั้งค่าโปรเจ็กต์แล้ว สิ่งแรกที่คุณต้องทำคือกำหนดค่า Spring Security

3. การกำหนดค่า (Configuring) Spring Security

Spring Security ให้บริการรักษาความปลอดภัยที่ครอบคลุมสำหรับทำแอพ Java จัดการทั้งการรับรองความถูกต้องและการอนุญาต โดยค่าเริ่มต้น จะเพิ่มการรับรองความถูกต้องตามรูปแบบพื้นฐานเพื่อป้องกันการร้องขอที่ไม่ได้รับอนุญาต

ในไดเร็กทอรี src/main/java/ ให้สร้างแพ็กเกจใหม่ชื่อ config และเพิ่มคลาสที่มีชื่อ SecurityConfig ในแพ็กเกจนี้ ชั้นนี้ควรขยาย WebSecurityConfigurerAdapter

ต่อไปนี้เป็นการกำหนดค่าง่ายๆ ที่ตั้งค่าผู้ใช้ที่กำหนดเองด้วยรหัสผ่านและบทบาท

import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().fullyAuthenticated().and().httpBasic();
    }

    @Bean
    public static NoOpPasswordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
}

ในการกำหนดค่าข้างต้น เรากำหนดผู้ใช้รายเดียวด้วยชื่อผู้ใช้ “user” รหัสผ่าน “password” และบทบาทเดียว “USER”

Spring Security รองรับรูปแบบการจัดเก็บรหัสผ่านที่หลากหลาย แต่เพื่อความง่าย เราได้ใช้ NoOpPasswordEncoder ซึ่งต้องใช้รหัสผ่านแบบข้อความล้วน สิ่งสำคัญคือต้องระบุว่าสิ่งนี้ไม่แนะนำสำหรับสถานการณ์การผลิต เนื่องจากมีความเสี่ยงด้านความปลอดภัยสูงที่เกี่ยวข้อง

4. การใช้ (Implementing) บริการรายละเอียดผู้ใช้ที่กำหนดเอง (Custom User Details Service)

ขั้นตอนต่อไปคือการใช้ (Implementing) UserDetailsService สำหรับแอปพลิเคชันของเรา บริการนี้โหลดข้อมูลเฉพาะของผู้ใช้ในระหว่างการตรวจสอบสิทธิ์ และมีความสำคัญในแผนการตรวจสอบสิทธิ์ส่วนใหญ่ เช่น เมื่อใช้ชื่อผู้ใช้และรหัสผ่านเพื่อเข้าสู่ระบบ

ภายใต้ package service ให้สร้างคลาสใหม่โดย CustomUserDetailsService ใช้อินเทอร์เฟซ UserDetailsService เราจะแทนที่เมธอด loadUserByUsername ซึ่งโหลดเอนทิตีผู้ใช้ตามชื่อผู้ใช้ และสามารถใช้ได้ทุกที่ที่ต้องการข้อมูลผู้ใช้

import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // here you can use a JPA repository to fetch the user from the database
        // for simplicity, let's just create a user directly
        return User.withUsername("user")
                .password(passwordEncoder().encode("password"))
                .roles("USER").build();
    }

    // don't forget the password encoder bean
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

ที่นี่ เรากำลังสร้างผู้ใช้โดยตรง แต่ในแอปพลิเคชันในโลกแห่งความเป็นจริง คุณจะดึงข้อมูลผู้ใช้จากฐานข้อมูลของคุณโดยใช้ข้อมูลที่มี username ให้

5. การดำเนินการอนุญาต (Authorization)

เมื่อตรวจสอบสิทธิ์แล้ว เรามาเริ่มที่การให้สิทธิ์กันเลย มันกำหนดไว้ในวิธีการ configure(HttpSecurity http) ในคลาส SecurityConfig ของเรา

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
            .antMatchers("/").permitAll()
            .and().httpBasic();
}

ในการกำหนดค่านี้ เราได้ตั้งกฎการเข้าถึงต่อไปนี้:

  • URL ที่ขึ้นต้นด้วย “/admin/” สามารถเข้าถึงได้โดยผู้ใช้ที่มีบทบาท “ADMIN” เท่านั้น
  • URL ที่ขึ้นต้นด้วย “/user/” สามารถเข้าถึงได้โดยผู้ใช้ที่มีบทบาท “ADMIN” หรือ “USER”
  • URL อื่นๆ ทั้งหมด (“/”) สามารถเข้าถึงได้โดยทุกคน

การรักษาความปลอดภัยในการทำแอพ Spring Boot ของคุณด้วยกลไกการพิสูจน์ตัวตนและการให้สิทธิ์เป็นสิ่งสำคัญของการทำเว็บแอปพลิเคชันใดๆ Spring Security มอบวิธีที่มีประสิทธิภาพในการจัดการด้านเหล่านี้ ลดจำนวนการจัดการความปลอดภัยแบบแมนนวลที่คุณต้องเขียนโค้ด

โปรดจำไว้ว่าตัวอย่างด้านบนนั้นค่อนข้างเรียบง่าย และคุณจะต้องมีการกำหนดค่าที่ซับซ้อนมากขึ้นสำหรับแอปพลิเคชันในโลกแห่งความเป็นจริง รวมถึงการเข้ารหัสรหัสผ่านและการจัดเก็บข้อมูลผู้ใช้อย่างปลอดภัย อย่างไรก็ตามหลักการยังคงเหมือนเดิม

การทำแอพด้วย Spring Boot ที่ปลอดภัย คุณสามารถมั่นใจได้ว่าข้อมูลของผู้ใช้ของคุณได้รับการปกป้อง ขณะที่ยังคงควบคุมว่าใครสามารถเข้าถึงส่วนต่าง ๆ ของการทำแอพของคุณได้


Spring Boot คืออะไร

Spring Boot คือ ตอนที่ 9 : การทดสอบหน่วย (Unit Testing) และการทดสอบการรวมเข้าด้วยกัน (Integration Testing)
Spring Boot คือ ตอนที่ 11 : การสร้าง RESTful Web Service