Spring Security로 OAuth2.0과 JWT 인증 구현하기

Spring Security로 OAuth2.0과 JWT 인증 구현하기
Spring Security는 Spring 기반의 프로젝트에서 보안을 처리하기 위한 강력한 프레임워크로, OAuth 2.0 및 JWT와 같은 인증 및 권한 부여 메커니즘을 구현하는 데 매우 유용합니다. OAuth 2.0은 서드파티 애플리케이션이 사용자의 리소스에 접근할 수 있는 권한을 부여하는 프로토콜이며, JWT(JSON Web Token)는 정보를 안전하게 전달하기 위한 개방형 표준입니다. Spring Security를 사용하여 OAuth 2.0 및 JWT를 구현하는 방법에 대해 알아보겠습니다. ### OAuth 2.0 구현하기 1. 의존성 추가: 먼저 프로젝트에 OAuth 2.0을 지원하는 의존성을 추가해야 합니다. `spring-security-oauth2` 의존성을 `pom.xml`에 추가합니다.
<pre class="wp-block-syntaxhighlighter-code">
<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.5.0.RELEASE</version>
</dependency>
</pre>
2. OAuth2 설정: `@EnableAuthorizationServer` 어노테이션을 사용하여 OAuth2 인증 서버를 구성합니다. 클라이언트 ID, 클라이언트 시크릿, 권한 부여 유형 등을 설정합니다.

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
               .withClient("client_id")
               .secret("client_secret")
               .authorizedGrantTypes("authorization_code")
               .scopes("read", "write")
               .redirectUris("http://localhost:8080/login/oauth2/code/custom");
    }
}

3. 보안 설정: `@EnableResourceServer` 어노테이션을 사용하여 OAuth2 리소스 서버를 구성합니다. 리소스 서버에서 보호 받을 엔드포인트 및 권한을 설정합니다.

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/api/**").authenticated()
            .anyRequest().permitAll();
    }
}

### JWT 구현하기 1. 의존성 추가: JWT를 사용하기 위해 `jjwt` 의존성을 추가합니다.
<pre class="wp-block-syntaxhighlighter-code">
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
</pre>
2. JWT 생성: JWT를 생성하는 유틸리티 클래스를 작성합니다.

public class JwtTokenUtil {

    private static final String SECRET_KEY = "secret";
    private static final long EXPIRATION_TIME = 86400000;

    public static String generateToken(String username) {
        return Jwts.builder()
                   .setSubject(username)
                   .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                   .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                   .compact();
    }

    public static String getUsernameFromToken(String token) {
        return Jwts.parser()
                   .setSigningKey(SECRET_KEY)
                   .parseClaimsJws(token)
                   .getBody()
                   .getSubject();
    }
}

3. JWT 인증: JWT를 사용하여 사용자를 인증하는 필터를 작성합니다.

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = extractTokenFromRequest(request);

        if (token != null && JwtTokenUtil.validateToken(token)) {
            String username = JwtTokenUtil.getUsernameFromToken(token);
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }

        filterChain.doFilter(request, response);
    }
}

Spring Security를 사용하여 OAuth 2.0 및 JWT를 구현하는 방법에 대해 간략히 살펴보았습니다. 이러한 설정을 통해 안전하고 효율적인 사용자 인증 및 권한 부여 메커니즘을 구현할 수 있습니다. 이를 통해 프로젝트의 보안성을 강화하고 사용자 경험을 향상시킬 수 있습니다.