반응형

전자정부프레임워크로 개발한 RESTful API는 외부로 데이터를 전달하거나 받을 수 있어 보안이 매우 중요합니다. 오늘은 Spring Security를 사용해 API 보안을 강화하는 방법을 알아보겠습니다.


1. API 보안의 필요성

  1. 인증(Authentication): 사용자가 누구인지 확인합니다.
  2. 인가(Authorization): 사용자가 어떤 작업을 수행할 수 있는지 결정합니다.
  3. 데이터 보호: 민감한 데이터를 안전하게 전송합니다.
  4. 악의적인 접근 방지: 불법적인 요청을 차단합니다.

2. Spring Security 의존성 추가

pom.xml 파일에 다음 의존성을 추가합니다.

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

3. 기본 인증 설정

Spring Security는 기본적으로 Basic Authentication을 제공합니다. 이를 설정하려면 SecurityConfig 클래스를 작성합니다.

3-1. 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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable() // CSRF 비활성화 (API 사용 시)
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/users/**").authenticated() // 인증이 필요한 경로
                .anyRequest().permitAll() // 그 외 경로는 허용
            )
            .httpBasic(); // Basic Authentication 활성화
        return http.build();
    }

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

3-2. 사용자 인증 데이터 정의

기본적으로 Spring Security는 메모리에 사용자 정보를 저장합니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
public class InMemoryUserDetailsService {

    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withUsername("admin")
                               .password(new BCryptPasswordEncoder().encode("password"))
                               .roles("ADMIN")
                               .build();
        return new InMemoryUserDetailsManager(user);
    }
}
  • username: admin
  • password: password
  • roles: ADMIN

4. API 호출 테스트

4-1. 인증 없이 요청

curl -X GET http://localhost:8080/users

  • 응답: 401 Unauthorized

4-2. 인증 포함 요청

curl -X GET http://localhost:8080/users -u admin:password

  • 응답: 사용자 데이터 반환

5. JWT(JSON Web Token) 인증 적용

API의 확장성을 위해 JWT를 사용하는 방법도 소개합니다.

5-1. JWT 의존성 추가

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
</dependency>

5-2. JWT 생성 및 검증 서비스

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Service;

import javax.crypto.SecretKey;
import java.util.Date;

@Service
public class JwtService {

    private final SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

    public String generateToken(String username) {
        return Jwts.builder()
                   .setSubject(username)
                   .setIssuedAt(new Date())
                   .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1시간 유효
                   .signWith(key)
                   .compact();
    }

    public boolean validateToken(String token) {
        try {
            Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

6. 마무리

오늘은 RESTful API에 Spring Security와 JWT를 활용한 보안을 적용하는 방법을 알아보았습니다. 인증과 인가는 API 개발의 핵심입니다. 다음 단계에서는 API 문서화를 위한 Swagger 적용 방법을 다룰 예정입니다.

반응형

+ Recent posts