스프링 시큐리티 시작하기

Dev-Whale·2024년 9월 14일
0

SpringSecurity 정복기

목록 보기
1/1
post-thumbnail

1. 스프링 시큐리티란?

  • 스프링 프레임워크를 기반으로 하는 애플리케이션의 보안처리를 쉽게 해주는 프레임워크
  • 웹 어플리케이션뿐만 아니라 REST API에서도 사용가능
  • 주요기능
    - 인증(Authentication) : 사용자가 누구인지 확인하는 과정
    - 인가(Authorization) : 사용자가 요청한 작업을 할 수 있는 권한이 있는지 확인하고 부여하는 과정
    - CSRF 보호 : Cross-Site Request Forgery 방지 -> 이것에 대한 정리 따로 필요
    - 세션 관리 : 세션을 관리하고 보호하는 기능
    - OAuth2, JWT 등과의 통합 : 다양한 인증 방식과의 손쉬운 통합

2. 스프링 시큐리티 기본 설정

의존성 추가

  • 스프링 시큐리티 의존성 : spring-boot-starter-security

Maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Gradle 설정

implementation 'org.springframework.boot:spring-boot-starter-security'

의존성 추가에 따른 특징

  • 기본적으로 모든 엔드포인트 보호 -> 모든 페이지에 인증 필요(기본 로그인 페이지 제공)
  • 엔드포인트보호를 사용하지 않으려면 필터체인에 권한 허용 로직을 넣어주어야함

3. 사용자 인증 구현

SecurityConfig

  • 기본적인 사용자 인증 구현
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((requests) -> requests
                .antMatchers("/", "/home").permitAll()  // 홈 페이지는 모든 사용자가 접근 가능
                .anyRequest().authenticated()           // 그 외의 모든 요청은 인증 필요
            )
            .formLogin((form) -> form // 폼 로그인 사용
                .loginPage("/login")  // 커스텀 로그인 페이지 설정
                .permitAll()
            )
            .logout((logout) -> logout.permitAll());    // 로그아웃은 누구나 가능
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build());
        return manager;
    }
}
  • 간단하게 InMemory에 저장된 사용자 정보로 설정하는 방법(아이디:user,비밀번호:password)
    - 확장하고 싶으면 해당 데이터를 DB에 저장해서 사용하면 된다(새로운 포스트로 정리)
  • /home 페이지는 인증없이 누구나 접근이 가능, 그 외의 페이지는 인증이 필요하다.

사용자 권한 설정

  • 사용자 권한에 따라 페이지 접근을 제한할 수 있다.

관리자 권한 추가

@Bean
public UserDetailsService userDetailsService() { // Inmemory 설정
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(User.withDefaultPasswordEncoder()
        .username("user")
        .password("password")
        .roles("USER") // 'USER' 라는 권한 추가
        .build());
    manager.createUser(User.withDefaultPasswordEncoder()
        .username("admin")
        .password("adminpass")
        .roles("ADMIN") // 'ADMIN' 이라는 권한 추가
        .build());
    return manager;
}

권한별 페이지 접근 제한

http
    .authorizeHttpRequests((requests) -> requests
        .antMatchers("/", "/home").permitAll()
        .antMatchers("/admin/**").hasRole("ADMIN")  // 관리자만 접근 가능한 페이지
        .anyRequest().authenticated()
    );

5. 커스텀 로그인 페이지

  • 스프링 시큐리티는 기본 로그인페이지를 제공하지만, 우리가 원하는 스타일로 로그인 페이지를 커스텀 할 수있습니다.

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>로그인</title>
</head>
<body>
    <h2>로그인 페이지</h2>
    <form th:action="@{/login}" method="post">
        <div>
            <label>사용자 이름: </label>
            <input type="text" name="username"/>
        </div>
        <div>
            <label>비밀번호: </label>
            <input type="password" name="password"/>
        </div>
        <div>
            <button type="submit">로그인</button>
        </div>
    </form>
</body>
</html>
  • 위처럼 작성한 파일을 src/main/resources/templates/login.html 경로에 추가하면, /login 경로로 이동할 때 커스텀 로그인 페이지가 표시됩니다.
  • 사용자이름, 비밀번호의 username, password는 스프링 시큐리티에 등록된 네이밍을 수정하면 수정이 가능합니다.

6. 로그아웃 기능 구현

  • 스프링 시큐리티는 기본 로그아웃 기능도 제공합니다.
  • 로그아웃 시 세션을 무효화하고, 쿠키를 삭제한 후 기본적으로 홈 페이지로 리다이렉션 합니다.
http
    .logout((logout) -> logout
        .logoutUrl("/logout")
        .logoutSuccessUrl("/home")
        .permitAll()
    );
  • 로그아웃 버튼을 HTML에 추가할 수도 있습니다.
<form th:action="@{/logout}" method="post">
    <button type="submit">로그아웃</button>
</form>

7. 마무리

스프링 시큐리티를 사용하여 간단한 로그인, 로그아웃 기능과 권한 설정을 구현하는 방법을 알아보았습니다. 여기서는 매우매우 기본적인 설정을 다루었지만, 스프링 시큐리티는 OAuth2, JWT, 세션 관리, CSRF 보호 등의 다양한 보안 기능을 제공합니다. 이를 확장하여 더 복잡한 애플리케이션에서도 강력한 보안을 설정할 수 있습니다.

참조

spring-security-samples

profile
개발하는 고래(파인만이 되고싶어)

0개의 댓글