우당탕탕
[Spring] 초보자를 위한 Spring Security: JWT로 웹 앱 보안 강화하기 본문
Spring Security를 활용하여 웹 애플리케이션의 인증 및 인가를 설정하고 JWT를 통한 보안 강화를 구현하는 방법
1. Spring Security란?
Spring Security는 Java 애플리케이션을 위한 강력하고 커스터마이징이 가능한 보안 프레임워크이다. 이 프레임워크는 웹 애플리케이션의 보안을 강화하는 데 필수적이며, 인증(Authentication)과 인가(Authorization) 기능을 제공한다.
2. 인증(Authentication)과 인가(Authorization)
- 인증(Authentication)
사용자가 누구인지 확인하는 과정으로 예를 들어, 로그인 시 사용자가 입력한 아이디와 패스워드가 맞는지 검증하는 것을 인증이라 한다.
- 인가(Authorization)
인증된 사용자가 특정 리소스에 접근할 수 있는 권한이 있는지를 결정하는 과정을 인가라고 한다. 예를 들어, 관리자만 특정 페이지에 접근할 수 있도록 설정하는 것이 인가이다.
이 두 가지 개념이 웹 애플리케이션의 보안을 유지하는 데 핵심적인 역활을 한다.
3. Spring Security 기본 인증 설정
Spring Security를 사용하기 위해서는 먼저 Gradle과 Maven을 통해 의존성을 추가해야 한다.
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Gradle
implementation 'org.springframework.boot:spring-boot-starter-security'
의존성 주입까지 완료되었다면 이제 Spring Security를 설정하기 위해 WebSecurityConfigurerAdapter를 상속받는 클래스를 생성한다. 이 클래스는 Spring Security의 설정을 커스터마이즈 할 수 있는 기본 구조를 제공하는 클래스이다.
WebSecurityConfigurerAdaper상속
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity // Spring Security 기능을 활성화
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() // 요청에 대한 권한 설정 시작
.antMatchers("/public/**").permitAll() // /public/** URL은 인증 없이 접근 가능
.antMatchers("/api/admin").hasRole("ADMIN") // ADMIN 권한이 필요
.antMatchers("/api/user").hasRole("USER") // USER 권한이 필요
.anyRequest().authenticated() // 나머지 요청은 인증이 필요함
.and()
.httpBasic(); // 기본 인증 사용
}
}
위의 코드에서 사용한 것 처럼 @EnableWebSecurity를 활용하여 Spring Security 기능을 활성화시키고. antMatchers를 통해 해당 URL을 지정,. hasRole을 이용하여 권한에 대한 체크를 진행한다. (/**은 하위 경로를 모두 포함하는 것을 의미한다. 예를 들어 /public/sample , /public/mozzi 와 같은 url을 모두 포함한다)
4. JWT를 이용한 인증
JWT(JSON Web Token)는 사용자 인증을 위한 안전한 방법이다. 사용자가 로그인을 하면 서버는 JWT를 생성하여 클라이언트에 전달하고 이후 클라이언트는 이 토큰을 Authorization 헤더에 포함하여 요청하게 된다.
JWT 생성 예시
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username) // 사용자 이름을 토큰의 주제로 설정
.setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1일 후 만료
.signWith(SignatureAlgorithm.HS256, "secret-key") // 비밀 키로 서명
.compact(); // 토큰 생성
}
위에서 작성한 generateToken을 활용해서 토큰 리턴하는 API를 간단하게 작성해보면 아래와 같다
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api") // API 요청의 기본 경로
public class UserController {
@PostMapping("/login") // 로그인 요청 처리
public ResponseEntity<String> login(@RequestBody UserLoginDto loginDto) {
// 사용자 인증 로직
String token = generateToken(loginDto.getUsername()); // JWT 생성
return ResponseEntity.ok(token); // 생성된 토큰 반환
}
@GetMapping("/user") // 사용자 정보 요청
@PreAuthorize("hasRole('USER')") // USER 권한이 있어야 접근 가능
public ResponseEntity<String> getUserInfo() {
return ResponseEntity.ok("User Info"); // 사용자 정보 반환
}
}
여기서 @PreAuthorize("hasRole('USER')")로 USER권한을 체크하게 되는데 어떤 사용자가 USER인지 판단은 어디서 하는 걸까?
@PreAuthorize 어노테이션이 붙은 메서드가 호출될 때, Spring Security는 현재 인증된 사용자의 UserDetails 객체를 확인하여 해당 사용자가 필요한 권한(예: USER, ADMIN)을 가지고 있는지를 판단하게 된다.
이처럼 Spring Security를 통해 웹 애플리케이션의 보안을 강화할 수 있다. 기본 인증을 설정하고, JWT를 사용하여 인증을 구현하며, 권한 관리를 통해 사용자 접근을 제어할 수 있으며, 이를 통해 보다 안전한 애플리케이션을 개발할 수 있다.
'Tech > Spring' 카테고리의 다른 글
[Spring] 스프링 @Transactional(트랜잭션)에 대해 이해하기 (0) | 2024.09.23 |
---|---|
[Spring] JPA에서 Persistable 인터페이스로 성능 최적화하기: isNew() 메서드 활용법 (0) | 2024.08.16 |
[Spring] ControllerAdvice와 ExceptionHandler에 대해 (1) | 2022.09.27 |
[Spring] IoC(Inversion of Control)과 DI(Dependency Injection) 이란? (0) | 2022.09.01 |
[Spring] 필터(Filter)와 인터셉터(Interceptor) 차이 (1) | 2022.08.23 |