반응형

이번에는 Spring Security를 활용해 애플리케이션에 인증(Authentication)과 권한 부여(Authorization)를 추가하는 방법에 대해 알아보겠습니다.


1. Spring Security란?

Spring Security는 Spring 생태계에서 가장 널리 사용되는 보안 프레임워크입니다. 사용자 인증과 권한 부여, 세션 관리, 암호화, CSRF 방어 등의 기능을 제공합니다.


2. 프로젝트에 Spring Security 추가

(1) 의존성 추가

pom.xml 파일에 Spring Security 관련 의존성을 추가합니다.

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

(2) 기본 보안 설정

Spring Security를 추가하면 기본적으로 모든 엔드포인트가 보호되며 /login 페이지가 생성됩니다.


3. Spring Security 설정

Spring Security의 동작을 커스터마이징하려면 SecurityConfig 클래스를 생성합니다.

import org.springframework.context.annotation.Bean;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")  // ADMIN만 접근 가능
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") // USER, ADMIN 접근 가능
            .antMatchers("/", "/public/**").permitAll() // 모든 사용자 접근 가능
            .and()
            .formLogin()
            .loginPage("/login") // 사용자 정의 로그인 페이지
            .permitAll()
            .and()
            .logout()
            .permitAll();
    }
}

4. 메모리 기반 사용자 인증 추가

개발 단계에서는 간단하게 메모리 기반 사용자 인증을 설정할 수 있습니다.

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("user").password(passwordEncoder().encode("user123")).roles("USER")
        .and()
        .withUser("admin").password(passwordEncoder().encode("admin123")).roles("ADMIN");
}

위 코드는 두 개의 사용자 계정(user, admin)을 생성합니다.


5. 커스텀 로그인 페이지 구현

(1) 컨트롤러 생성

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

@Controller
public class LoginController {

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

(2) 로그인 페이지 작성

src/main/resources/templates/login.html 파일을 생성합니다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>로그인</title>
</head>
<body>
<h1>로그인</h1>
<form th:action="@{/login}" method="post">
    <label for="username">아이디:</label>
    <input type="text" id="username" name="username" />
    <br />
    <label for="password">비밀번호:</label>
    <input type="password" id="password" name="password" />
    <br />
    <button type="submit">로그인</button>
</form>
</body>
</html>

6. 권한 기반 페이지 보호

Spring Security는 엔드포인트별로 접근 권한을 지정할 수 있습니다. 아래는 관리자 페이지(/admin)와 사용자 페이지(/user)에 대한 예제입니다.

(1) 컨트롤러 작성

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

@Controller
public class PageController {

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

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

(2) 템플릿 작성

  • admin.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>관리자 페이지</title>
</head>
<body>
<h1>관리자 전용 페이지</h1>
<p>여기는 관리자만 접근할 수 있습니다.</p>
</body>
</html>

 

  • user.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>사용자 페이지</title>
</head>
<body>
<h1>사용자 페이지</h1>
<p>여기는 일반 사용자와 관리자가 접근할 수 있습니다.</p>
</body>
</html>

7. 비밀번호 암호화

Spring Security는 비밀번호를 암호화해 저장하는 것을 권장합니다. BCryptPasswordEncoder를 사용해 비밀번호를 암호화합니다.

public String encodePassword(String rawPassword) {
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    return encoder.encode(rawPassword);
}

8. 테스트

  1. 브라우저에서 애플리케이션을 실행합니다.
  2. /login 페이지로 이동하여 로그인합니다.
  3. 로그인한 사용자 계정에 따라 접근 가능한 페이지(/admin, /user)를 확인합니다.
반응형

+ Recent posts