Spring Security ด้วย Spring Boot 2.0

Chiwa Kantawong (Pea)
2 min readFeb 15, 2019

--

วันนี้ผมจะมีบทความง่าย ๆ เกี่ยวกับการสร้าง secured endpoints ด้วย Spring Security ใน Sping Boot 2.0.x นะครับ

เราจะมาสร้าโปรเจคส์ด้วย maven กันนะครับ โครงสร้างตามนี้ครับ

สร้าง pom ไฟล์ตามนี้เลยครับ

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>4.0.0</modelVersion>

<groupId>com.zengcode.sping.security</groupId>
<artifactId>zengcode-spring-security</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>

ต่อไปเรามา Extends WebSecurityConfigurerAdapter และกำหนด security rules กัน

กำหนด user “admin” ให้เข้าถึง /admin และ /customer ได้
กำหนด user “customer” ให้เข้าถึง/customer ได้

package com.zengcode.spring.security.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.AccessDeniedHandler;

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {


@Override
protected void configure(HttpSecurity http) throws Exception {

http.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/", "/welcome").permitAll()
.antMatchers("/admin").hasAnyRole("ADMIN")
.antMatchers("/customer").hasAnyRole("CUSTOMER", "ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.defaultSuccessUrl("/welcome")
.and()
.logout()
.permitAll();

}

@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.inMemoryAuthentication()
.withUser("customer").password("{noop}123").roles("CUSTOMER")
.and()
.withUser("admin").password("{noop}123").roles("ADMIN");
}

@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/templates/**","/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");
}
}

ไฟล์ login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
>

<head>
<title>Spring Security Tutorial</title>
<link rel="stylesheet" type="text/css" th:href="@{/css/login.css}"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

<body>


<div class="container">

<form th:action="@{/login}" method="POST" class="form-signin">
<h3 class="form-signin-heading" th:text="Welcome"></h3>
<br/>

<input type="text" id="username" name="username" th:placeholder="Username"
class="form-control"
/> <br/>
<input type="password" th:placeholder="Password"
id="password" name="password" class="form-control"
/> <br/>

<div align="center" th:if="${param.error}">
<p style="font-size: 20; color: #FF1C19;">Email or Password invalid, please verify</p>
</div>
<button class="btn btn-lg btn-primary btn-block" name="Submit" value="Login" type="Submit"
th:text="Login"
></button>
</form>
</div>
</body>
</html>

ส่วนไฟล์ html อื่นๆ ก็แค่ print static text ธรรมดาครับ

เมื่อรัน project แล้วพยายามเข้า http://localhost:8080/admin หรือ /customer จะ redirect ไปหน้า http://localhost:8080/login อัตโนมัตครับ

เมื่อ login แล้วก็จะเข้าไปหน้าต่างๆ ที่มี permission แต่ถ้าไม่มี permission เช่น login เป็น customer แต่เข้าหน้า admin ก็จะ redirect ไปหน้า error page ครับ

--

--

Chiwa Kantawong (Pea)
Chiwa Kantawong (Pea)

Written by Chiwa Kantawong (Pea)

Software Development Expert at Central Tech

No responses yet