이번글에서는 Spring Security의 Default Configuartion에 대해 알아보도록 하겠습니다.
1. Unsecured Spring Boot App
이번글에서 사용한 source code는 여기에서 확인할 수 있습니다.
먼저 현재 프로젝트의 구조는 다음과 같습니다.
1-1) dependency
build.gradle
plugins {
id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.tutorial'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
dependency에는 가장 기본적인 요소들만 포함하였으며, 아직까지 dependcy에 spring-security를 포함시키지 않았습니다.
1-2) templates
view는 spring boot의 thymeleaf를 사용하겠습니다.
아래와 같이 간단히 화면을 구성했습니다.
각 index.html 페이지는 단순히 해당 페이지가 어떠한 페이지인가를 보여주는 화면입니다.
admin/index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:insert="fragments.html :: headerfiles"></head>
<body>
<header th:insert="fragments.html :: nav"></header>
<!-- Page content goes here -->
<div class="container">
<p>This is Admin\Index. Only people with role_admin can see this.</p>
</div>
</body>
</html>
management/index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:insert="fragments.html :: headerfiles"></head>
<body>
<header th:insert="fragments.html :: nav"></header>
<!-- Page content goes here -->
<div class="container">
<p>This is Management\Index. Only people with role_management can see this</p>
</div>
</body>
</html>
profile/index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head th:insert="fragments.html :: headerfiles"></head>
<body>
<header th:insert="fragments.html :: nav"></header>
<!-- Page content goes here -->
<div class="container">
<p>This is User Profile\Index. Only authenticated people can see this</p>
</div>
</body>
</html>
fragement.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<!-- Fragment #1 : Headerfiles contains css and js references -->
<head th:fragment="headerfiles">
<title>Introduction to SpringBoot Security</title>
<meta charset="UTF-8"/>
<link th:href="@{~/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{~/fontawesome/css/all.css}" rel="stylesheet">
</head>
<body>
<!-- Fragment #2 : Navbar contains nav links -->
<div th:fragment="nav">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Boot Security</a>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="#" th:href="@{~/index}"><i class="fa fa-home"></i>Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:href="@{~/profile/index}">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:href="@{~/admin/index}">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:href="@{~/management/index}">Management</a>
</li>
</ul>
</div>
</nav>
</div>
</body>
</html>
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:insert="fragments.html :: headerfiles"></head>
<body>
<header th:insert="fragments.html :: nav"></header>
<!-- Page content goes here -->
<div class="container">
<div class="jumbotron">
<h1 class="display-4">Hello, Spring Boot Security!</h1>
<p class="lead">This is the home page of our web application. Anyone can access it, even if they have not signed in.</p>
<hr class="my-4">
<p>Using this example, you will become more familiar with Spring Security concepts:)</p>
<p class="lead">
<a class="btn btn-primary btn-lg" href="https://spring.io/projects/spring-security" role="button">Learn more about Spring Security</a>
</p>
</div>
</div>
</body>
</html>
1-3) controller
controller는 url 호출시 그에 맞는 thymealeaf 페이지를 보여줄 수 있도록 생성했습니다.
AdminController
@Controller
@RequestMapping("admin")
public class AdminController {
@GetMapping("index")
public String index(){
return "admin/index";
}
}
HomeController
@Controller
@RequestMapping("/")
public class HomeController {
@GetMapping("index")
public String index(){
return "index";
}
}
ManagementController
@Controller
@RequestMapping("management")
public class ManagementController {
@GetMapping("index")
public String index(){
return "management/index";
}
}
ProfileController
@Controller
@RequestMapping("profile")
public class ProfileController {
@GetMapping("index")
public String index(){
return "profile/index";
}
}
추가적으로 아래와 같이 REST API Controller도 하나 생성하겠습니다.
PublicRestApiController
@RestController
@RequestMapping("api/public")
public class PublicRestApiController {
public PublicRestApiController(){}
@GetMapping("test1")
public String test1(){
return "API Test 1";
}
@GetMapping("test2")
public String test2(){
return "API Test 2";
}
}
1-4) launch application
위와 같이 구성된 project를 실행킨 뒤 localhost:8080으로 접근해보겠습니다.
화면 상단에는 Profile / Admin / Management tab이 존재하며, 현재는 어떠한 security도 적용되어 있지 않기 때문에 누구나 해당 tab으로 접근가능한 것을 확인할 수 있습니다.
Profile Tab
Admin Tab
Management Tab
2. Enable Security
이제 위의 spring boot app에 security를 적용해보도록 하겠습니다.
2-1) add security dependency
build.gradle 파일에 아래 2개의 dependency를 추가합니다.
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
간단히 위의 2개의 dependency만 추가하는 것 만으로도, spring security의 default configration을 사용할 수 있습니다.
view로 thymeleaf를 사용하지 않는 경우에는 첫번째 dependency만 추가하면 됩니다.
2-2) launch security enabled app
이제 동일한 spring boot app을 실행시켜 보겠습니다.
정상적으로 app이 실행된 뒤 console 창을 확인해보면 위와 같이 비밀번호가 하나 임의로 생성되는 것을 확인할 수 있습니다.
이는 spring-security의 defualt configuration이 생성해주는 임의의 password로 사용자는 해당 password를 사용해 app에 접근할 수 있게됩니다.
이 password는 app이 실행될때마다 random으로 생성됩니다.
동일하게 localhost:8080으로 접근해보면 아래와 같이 login page로 redirect 되는 것을 확인할 수 있습니다.
로그인 페이지를 만든적이 없으시다구요..?? 😅
맞습니다. 위의 login 페이지는 spring-security가 생성한 page로 사용자가 생성한 페이지가 아닙니다.
해당 페이지에서 username에는 user를 password에는 앞서 확인한 default password를 입력해야지만 spring boot app으로 입장할 수 있습니다.
• userName : user
• password : 6be3c9c6-af95-461a-a318-17c68d951ebd
2-3) remove generated user & password
만약 직접 정의한 user와 password를 사용하고 싶으면 아래와 같이 application.yml에 입력해 사용합니다.
이후에는 login page에서 위의 username과 password를 입력하면 됩니다.
참고 자료 : https://www.youtube.com/playlist?list=PLVApX3evDwJ1d0lKKHssPQvzv2Ao3e__Q
추천서적
파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
'Spring > Security' 카테고리의 다른 글
[Spring Security] Role Based Authorization - Spring Boot (3) (0) | 2020.09.08 |
---|---|
[Spring Security] HTTP Basic Authentication - Spring Boot (2) (0) | 2020.09.08 |
[Spring Security] SSL & HTTPS (0) | 2020.09.08 |
[Spring Security] JWT Authentication (0) | 2020.09.08 |
[Spring Security] Form Based Authentication (0) | 2020.08.31 |