Spring Boot Security 설정

🌿 Security

스프링 시큐리티(Spring Security)란 스프링 기반의 어플리케이션의 보안(인증과 권한)을 담당하는 프레임워크이다.
보안과 관련해서 체계적으로 많은 옵션들을 지원해 주며, 필터(Filter) 기반으로 동작하기 때문에 스프링 MVC 와 분리되어 관리 및 동작한다.

  • 인증(Authentication) : 해당 사용자가 본인이 맞는지 확인하는 과정
  • 인가(Authorization) : 해당 사용자가 요청하는 자원을 실행할 수 있는 권한이 있는가를 확인하는 과정

🌿 시큐리티 설정하기

1. build.gradle에 dependency 추가

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
testImplementation 'org.springframework.security:spring-security-test'

security6사용을 위해선 Spring boot3.x 이상 사용해야함

2. SecurityConfig파일 생성

securityAuto

SecurityConfig.java

package com.team.mztelecom.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity // 시큐리티 관리 설정
public class SecurityConfig {

	@Bean // 빈으로 등록해주면 자동으로 필터에 시큐리티 설정을 커스텀으로 진행 할 수 있음
	protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		
		http
		 	// 특정한 경로 허용, 거부 설정 (작성은 람다식)
			.authorizeHttpRequests((auth) -> auth 
					// permitAll() -> 를 사용하면 권한이 없는 모든 사람들이 들어갈 수 있음.
					.requestMatchers("/", "/**.do", "/js/**", "/css/**","/images/**", "/login").permitAll()
					
					// ADMIN이라는 권한을 가진 사람만 접속 가능
					.requestMatchers("/admin").hasRole("ADMIN")
					
					// ADMIN, USER 권한을 가진 사람만 접속 가능
					.requestMatchers("/myPage/**", "/purRevWrite").hasAnyRole("ADMIN","USER")
					.anyRequest().authenticated()
		    )
			// 권한이 없는 사람이 접속하려고하면 로그인 페이지로 자동연결 되는데
			// login 페이지가 없으면 시큐리티 자체 로그인 페이지로 넘어감
			.formLogin(formLogin -> formLogin
					.loginPage("/login") 
			)
			.logout((logout) -> logout.logoutUrl("/logout"))
			
			// 소셜 로그인 
			.oauth2Login((oauth2) -> oauth2.loginPage("/login"));

        return http.build();

	}
	
	// 패스워드 암호화 시켜주는 거
	@Bean
	BCryptPasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
}

  • @EnableWebSecurity: Spring Security를 활성화하여 웹 보안 설정을 관리하는 어노테이션
  • SecurityFilterChain filterChain(HttpSecurity http): 보안 필터를 커스터마이징하기 위해 빈으로 등록된 메서드, HTTP 보안 설정을 정의 authorizeHttpRequests(): 특정 URL 경로에 대한 접근 권한을 설정하는 메서드, permitAll()을 통해 무조건 접근을 허용하거나 hasRole() 및 hasAnyRole()을 이용하여 특정 권한을 가진 사용자만 접근을 허용할 수 있다.
  • formLogin(): 로그인 페이지를 지정하는 메서드, 사용자가 로그인하지 않은 상태에서 보호된 페이지에 접근하려고 할 때 자동으로 로그인 페이지로 이동시킴
  • logout(): 로그아웃을 처리하기 위한 메서드, 로그아웃 URL을 설정하여 사용자가 로그아웃할 수 있도록 함.
  • oauth2Login(): OAuth2를 이용한 소셜 로그인 설정을 담당하는 메서드, 소셜 로그인 페이지를 지정
  • BCryptPasswordEncoder passwordEncoder(): 패스워드를 BCrypt 해싱하여 암호화하는 데 사용되는 빈을 등록

이렇게 초기 세팅을 했는데,

.requestMatchers("/", "/**.do", "/js/**", "/css/**","/images/**", "/login").permitAll()

이 부분 "/**.do"은 권한이 걸려서 권한없이 접근이 가능한 페이지가 접근이 안돼는 이슈가 발생해서 넣게 되었다.
근데 생각해보니 프로그래밍은 위에서 부터 아래로 실행 됨.

수정된 코드 👇🏻

.authorizeHttpRequests((auth) -> auth 
	.requestMatchers("/admin").hasRole("ADMIN")
	.requestMatchers("/myPage/**", "/purRevWrite").hasAnyRole("ADMIN","USER")
	.requestMatchers("/**" , "/js/**", "/css/**","/images/**", "/login").permitAll()
	.anyRequest().authenticated()
)
  • 권한을 한번에 써줘도 괜찮지만 컨트롤러에서도 설정이 가능함
@GetMapping(value = "/login")
@PreAuthorize("isAnonymous()")
public String login(Locale locale, Model model) {
	return "content/login";
}

@GetMapping(value = "/cart")
@PreAuthorize("isAuthenticated()")
public String cart(Locale locale, Model model) {
	return "content/cart";
}

Leave a comment