본문 바로가기
Programming/Spring Security

[Spring Boot] Spring Security (1) - 기본 프로젝트 생성

by 주리니e 2022. 7. 21.
728x90

[Spring Boot] Spring Security (1) - 기본 프로젝트 생성

 

 

개발환경

  • Eclipse IDE 2022-06
  • Spring Boot 2.7.2
  • Gradle 7.0
  • Lombok
  • PostgreSQL

Spring Security는 Spring Boot의 하위 프레임 워크이며 Java 어플리케이션에 인증과 권한 부여를 제공하는데 중점을 둔 프레임워크이다. Spring에서는 사실상 Spring Security를 표준으로 하여 보안기능을 제공하며 필터기반으로 처리한다. 사용자의 ID와 PASSWORD를 입력받아 인증을 하고 역할 및 권한을 부여할 수 있으며 CSRF(Cross Stie Script Forgery) 같은 취약점에도 대응이 가능하다. 우선 샘플 프로젝트를 생성하여 얕은 지식과 기능을 하나하나 채워가보도록 하자.

 

패키지 구조

  • build.gradle
plugins {
	id 'org.springframework.boot' version '2.7.2'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
	id 'war'
}

group = 'com.lombok'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
    
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

 

Please sign in

http://localhost:8080/login

프로젝트 생성 후 서버를 구동해서 들어가면 필자가 만들어 놓은 페이지는 없지만 위 사진과 같이 Spring Security에서 제공하는 Login 페이지가 나온다.  Spring Security는 설정을 하지 않으면 기본적으로 모든 페이지에 권한을 체크한다. 지금부터 웹 페이지에 접속하면 방문자나 회원이 들어갈 수 있는 홈 화면, 로그인 화면, 회원만 들어갈 수 있는 화면 이렇게 세가지의 화면을 만들어보자.

  • application.properties 
# Thymeleaf 템플릿 연결
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

 

  • SecurityConfiguration.java
package com.example.security;

import org.springframework.context.annotation.Bean;
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.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
public class SecurityConfiguration {

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		/* @formatter:off */
		http
			.authorizeRequests()
				.antMatchers("/", "/home").permitAll() // 설정한 리소스의 접근을 인증절차 없이 허용
				.anyRequest().authenticated() // 그 외 모든 리소스를 의미하며 인증 필요
				.and()
			.formLogin()
				.loginPage("/login") // 기본 로그인 페이지
				.permitAll()
				.and()
			.logout()
				.permitAll();
		
		return http.build();
		/* @formatter:on */
	}

	@Bean
	public UserDetailsService userDetailsService() {
		/* @formatter:off */
		UserDetails user =
			 User.withDefaultPasswordEncoder()
				.username("user")
				.password("password")
				.roles("USER")
				.build();
		/* @formatter:on */

		return new InMemoryUserDetailsManager(user); // 메모리에 사용자 정보를 담는다.
	}
}

User 클래스의 withDefaultPasswordEncoder 메소드는 Deprecated 되어 있으며 실제 운영서버에서는 사용하지 말아야 한다. 샘플코드에서만 다루고 다음 시간부터는 사용하지 않을 예정이다.

 

  • HomeController.java
package com.example.security.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

	@GetMapping({ "/", "/home" })
	public String home() {
		return "home";
	}

	@GetMapping("/login")
	public String login() {
		return "login";
	}

	@GetMapping("/hello")
	public String hello() {
		return "hello";
	}
}

 

  • home.html
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Spring Security Example</title>
</head>
<body>
	<h1>Welcome!</h1>
	<p>
		Click <a th:href="@{/hello}">here</a> to see a greeting.
	</p>
</body>
</html>

 

  • login.html
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Spring Security Example</title>
</head>
<body>
	<h1>Spring Security Login page</h1>
	<div th:if="${param.error}">Invalid username and password.</div>
	<div th:if="${param.logout}">You have been logged out.</div>
	<form th:action="@{/login}" method="post">
		<div>
			<label> User Name : <input type="text" name="username" /></label>
		</div>
		<br>
		<div>
			<label> Password : <input type="password" name="password" /></label>
		</div>
		<br>
		<div>
			<input type="submit" value="Sign In" />
		</div>
	</form>
</body>
</html>

 

  • hello.html
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<title>Hello World!</title>
</head>
<body>
	<h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
	<form th:action="@{/logout}" method="post">
		<input type="submit" value="Sign Out" />
	</form>
</body>
</html>

 

  • 사용자 화면 테스트

홈 화면

 

SecurityConfiguration.java에서 설정하였던 사용자 정보를 입력하자. user / password

로그인 화면

 

로그인 완료 화면

 

이렇게 기본적으로 Spring Security를 이용한 기본적인 페이지를 완성해보았다. 사용자는 홈화면에 접속하고 로그인을 하여 사용자 전용 페이지에 접근하는 시나리오이다. 다음 시간에는 데이터베이스로부터 사용자 정보를 가져와 로그인 인증을 해야겠다.

 

다음글 : [Spring Boot] Spring Security (2) - 회원가입 및 로그인 With PostgreSQL

 

[Spring Boot] Spring Security (2) - 회원가입 및 로그인 With PostgreSQL

Spring Security (2) - 회원가입 및 로그인 With PostgreSQL 개발환경 Eclipse IDE 2022-06 Spring Boot 2.7.2 Gradle 7.0 Lombok PostgreSQL 지난 시간에 이어서 이번에는 사용자 정보를 메모리에서 가져오는 것..

jiurinie.tistory.com

 

728x90

댓글