EP.1 ## JDBC authentication with Spring Security แบบเข้าใจง่าย
เราจะมาสร้างWeb Application แล้วใช้ JDBC Authentication ด้วย Spring Boot กันนะครับ มา initial project กันที่ https://start.spring.io/
เราจะใช้ H2 Database ซึ่งเป็น In Memory Database นะครับ เพื่อให้ง่ายไม่ต้อง install DBMS อย่างอื่น
pom.xml ของเราจะมีหน้าตาแบบนี้
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zengcode</groupId>
<artifactId>spring-security-jdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-security-jdbc</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ต่อไปเปิดโปรเจคส์ด้วย IntelliJ ครับ
แล้วมาสร้าง MainController.java กัน
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainController {
@GetMapping(value = "/")
public String welcome() {
return "Welcome";
}
@GetMapping(value = "/hello-world")
public String helloWorld() {
return "Hello World";
}
@GetMapping(value = "/users")
public String user() {
return "Welcome users.";
}
@GetMapping(value = "/admin")
public String admin() {
return "Welcome Admin.";
}
}
แล้วก็ run กันครับ
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainController {
@GetMapping(value = "/")
public String welcome() {
return "Welcome";
}
@GetMapping(value = "/hello-world")
public String helloWorld() {
return "Hello World";
}
@GetMapping(value = "/users")
public String user() {
return "Welcome users.";
}
@GetMapping(value = "/admin")
public String admin() {
return "Welcome Admin.";
}
}
ลองเข้าhttp://localhost:8080/hello-world ดู มันจะขึ้นหน้าให้ login แสดงว่า Spring Security ของเราทำงานแล้ว
ต่อไปเราจะให้ http://localhost:8080/hello-world ไม่ต้อง login ก็ให้สามารถเข้าใช้งานได้ เราจะ protect แต่ http://localhost:8080/users สำหรับ role user & admin และ http://localhost:8080/admin สำหรับ role admin เท่านั้น โดยการสร้าง SecurityConfiguration.java ดังนี้
package com.zengcode.springsecurityjdbc.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.sql.DataSource;
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.withDefaultSchema()
.withUser(User.withUsername("user").password("password").roles("USER"))
.withUser(User.withUsername("admin").password("password").roles("ADMIN"));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN", "USER")
.antMatchers("/").permitAll()
.and().formLogin();
}
@Bean
public PasswordEncoder getPasswordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
แล้วลองรันครับ ลองเข้า http://localhost:8080/hello-world เราจะเข้าได้แล้ว
ลองเข้า http://localhost:8080/user หรือ http://localhost:8080/admin ดูครับ จะเข้าไม่ได้ จะมีหน้าให้ login ลองป้อน user password ดูครับแล้วเข้า
http://localhost:8080/user จะเข้าได้แล้ว
แต่ก็ยังเข้า http://localhost:8080/admin ไม่ได้
ต่อไป เปิด browser เข้า http://localhost:8080/logout แล้วกดปุ่ม logout
มันก็จะ redirect ไปหน้าให้ login อีกที ตอนนี้ป้อน admin password
แล้วลองเข้า http://localhost:8080/admin ก็จะเข้าได้แล้ว
และก็ยังสามารถเข้า http://localhost:8080/users ได้ด้วย
ง่ายไหมล่ะครับ เอาไปปรับใช้กันนะครับ