[KB IT's Your Life TIL] 오늘의 학습 내용 : Spring Security + JWT 연동

JUN·2024년 9월 8일
0

KB IT's your life

목록 보기
10/16

오늘의 학습 내용

주요 개념 및 키워드

  • Spring Security: 기존의 세션 기반 보안 방식을 대신하여 JWT를 사용한 보안 시스템을 구축하는 핵심 프레임워크이다.
  • JWT: JSON 기반의 Web Token으로, 사용자의 인증 정보를 안전하게 전송하고 관리할 수 있는 방법이다. 서버는 사용자 요청마다 세션을 관리하지 않고, 토큰을 통해 요청을 검증할 수 있다.
  • AuthenticationManager: Spring Security에서 인증을 처리하는 핵심 구성 요소이며, JWT 검증 과정도 포함된다.
  • UsernamePasswordAuthenticationToken: JWT 발급을 위해 사용자의 이름과 비밀번호를 담고 인증을 시도하는 토큰 객체이다.
  • JwtTokenProvider: JWT 토큰을 생성하고 검증하는 역할을 한다. 해당 클래스에서 토큰 생성, 토큰 유효성 검증 등의 작업을 수행한다.

학습한 내용

1. JWT 인증 과정 개요

JWT 기반 인증은 세션을 사용하지 않고 클라이언트가 보관하는 토큰을 통해 인증을 처리하는 방식이다. 토큰은 서버에서 발급되며, 클라이언트는 매 요청마다 헤더에 토큰을 담아 인증을 받는다.

2. JWT의 구성

JWT는 세 가지 부분으로 구성된다:

  • Header: 토큰의 타입과 해싱 알고리즘이 명시된다.
  • Payload: 사용자 정보 및 클레임이 포함된다.
  • Signature: 비밀키를 이용해 서명되어 토큰의 무결성을 보장한다.

3. JWT 발급 및 검증

JWT는 사용자가 로그인 성공 시 발급되며, 이후 모든 요청에 포함되어 사용자의 인증을 증명한다. 서버는 요청이 들어올 때마다 JWT를 검증하여 사용자의 신원을 확인한다.

4. JWT 발급 코드 예시

public String createToken(String username, List<String> roles) {
    Claims claims = Jwts.claims().setSubject(username);
    claims.put("roles", roles);

    Date now = new Date();
    Date validity = new Date(now.getTime() + tokenValidity);

    return Jwts.builder()
            .setClaims(claims)
            .setIssuedAt(now)
            .setExpiration(validity)
            .signWith(SignatureAlgorithm.HS256, secretKey)
            .compact();
}

위 코드는 사용자 이름과 역할 정보를 담은 JWT를 생성하는 예시이다. 생성된 토큰은 클라이언트에 전달되고, 클라이언트는 이를 요청의 Authorization 헤더에 담아 인증을 시도한다.

5. JWT 검증 과정

public boolean validateToken(String token) {
    try {
        Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
        return !claims.getBody().getExpiration().before(new Date());
    } catch (JwtException | IllegalArgumentException e) {
        return false;
    }
}

이 코드는 JWT가 유효한지 검증하는 과정이다. 토큰이 만료되었거나 변조된 경우 검증이 실패한다.


Spring Security와 JWT 연동 흐름

  1. JWT 발급: 사용자가 로그인에 성공하면, 서버는 사용자 정보를 기반으로 JWT를 발급하여 클라이언트에게 전달한다.
  2. JWT 전달: 클라이언트는 이후 모든 요청에서 헤더에 JWT를 포함하여 서버에 전달한다.
  3. JWT 검증: 서버는 요청이 들어올 때마다 JWT의 유효성을 검증하고, 유효한 경우 해당 요청을 처리한다.
  4. Authorization: 검증된 JWT는 사용자의 권한 정보도 포함하고 있으므로, 권한에 따라 접근을 허용하거나 거부할 수 있다.

실습

1. JwtTokenProvider.java

토큰 발급과 검증을 담당하는 핵심 클래스이다.

2. JwtAuthenticationFilter.java

클라이언트로부터 전달받은 JWT를 검증하는 필터이다. Spring Security의 필터 체인에 포함되어 JWT가 유효한지 검증한다.

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain)
            throws ServletException, IOException {
        String token = resolveToken(request);
        if (token != null && jwtTokenProvider.validateToken(token)) {
            Authentication auth = jwtTokenProvider.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
        filterChain.doFilter(request, response);
    }
}

3. SecurityConfig.java

Spring Security 설정 파일로, JWT 기반 인증을 처리하는 설정이 포함된다.

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/auth/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }
}

새롭게 알게 된 점

기존의 세션 기반 인증에서 JWT를 사용하는 방식으로 전환하면서, 인증 상태를 유지하는 방식이 더 간결해지고 확장성 있게 변모했다.
Spring Security와 JWT의 결합은 RESTful API와 같은 무상태(stateless) 아키텍처에서 큰 장점을 제공한다는 것을 알게 되었다.


오늘의 회고

오늘은 Spring Security와 JWT 연동에 대해 학습했다. 가족 경조사로 인해 교육 과정에 직접 참여하지 못했지만, 이 주제의 중요성을 인식하고 독학으로 공부를 진행했다.

처음에는 복잡해 보였던 개념들이 차근차근 정리하면서 명확해졌고, 특히 JWT의 구조와 작동 방식에 대해 깊이 이해할 수 있었다.

이제 진행될 최종 프로젝트에 이 지식을 적용해 보면서 더 깊이 있는 이해를 할 수 있기를 기대한다.

profile
순간은 기록하고 반복은 단순화하자 🚀

0개의 댓글