Fix : 수정
This commit is contained in:
parent
185eafebe6
commit
ef87bfbb0b
@ -1,12 +1,12 @@
|
||||
package com.ktds.hi.member.config;
|
||||
|
||||
import com.ktds.hi.member.service.JwtTokenProvider;
|
||||
import com.ktds.hi.member.service.AuthService;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.util.StringUtils;
|
||||
@ -19,20 +19,26 @@ import java.io.IOException;
|
||||
* 요청 헤더의 JWT 토큰을 검증하고 인증 정보를 설정
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private final JwtTokenProvider tokenProvider;
|
||||
private final AuthService authService;
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
|
||||
try {
|
||||
String token = resolveToken(request);
|
||||
|
||||
if (StringUtils.hasText(token) && tokenProvider.validateToken(token)) {
|
||||
Authentication authentication = tokenProvider.getAuthentication(token);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
log.debug("JWT 토큰 인증 성공: {}", authentication.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("JWT 토큰 인증 실패", e);
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
package com.ktds.hi.member.config;
|
||||
|
||||
|
||||
import com.ktds.hi.member.config.JwtAuthenticationFilter;
|
||||
import com.ktds.hi.member.service.JwtTokenProvider;
|
||||
import com.ktds.hi.member.service.AuthService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -27,7 +28,6 @@ public class SecurityConfig {
|
||||
|
||||
@Qualifier("memberJwtTokenProvider")
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final AuthService authService;
|
||||
|
||||
/**
|
||||
* 보안 필터 체인 설정
|
||||
@ -40,16 +40,23 @@ public class SecurityConfig {
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(authz -> authz
|
||||
.requestMatchers("/api/auth/**", "/api/members/register").permitAll()
|
||||
.requestMatchers("/swagger-ui/**", "/api-docs/**").permitAll()
|
||||
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
|
||||
.requestMatchers("/actuator/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider, authService),
|
||||
UsernamePasswordAuthenticationFilter.class);
|
||||
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* JWT 인증 필터 빈
|
||||
*/
|
||||
@Bean
|
||||
public JwtAuthenticationFilter jwtAuthenticationFilter() {
|
||||
return new JwtAuthenticationFilter(jwtTokenProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* 비밀번호 암호화 빈
|
||||
*/
|
||||
@ -65,4 +72,45 @@ public class SecurityConfig {
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||
return config.getAuthenticationManager();
|
||||
}
|
||||
|
||||
// @Qualifier("memberJwtTokenProvider")
|
||||
// private final JwtTokenProvider jwtTokenProvider;
|
||||
// private final AuthService authService;
|
||||
//
|
||||
// /**
|
||||
// * 보안 필터 체인 설정
|
||||
// * JWT 인증 방식을 사용하고 세션은 무상태로 관리
|
||||
// */
|
||||
// @Bean
|
||||
// public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
// http
|
||||
// .csrf(csrf -> csrf.disable())
|
||||
// .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
// .authorizeHttpRequests(authz -> authz
|
||||
// .requestMatchers("/api/auth/**", "/api/members/register").permitAll()
|
||||
// .requestMatchers("/swagger-ui/**", "/api-docs/**").permitAll()
|
||||
// .requestMatchers("/actuator/**").permitAll()
|
||||
// .anyRequest().authenticated()
|
||||
// )
|
||||
// .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider, authService),
|
||||
// UsernamePasswordAuthenticationFilter.class);
|
||||
//
|
||||
// return http.build();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 비밀번호 암호화 빈
|
||||
// */
|
||||
// @Bean
|
||||
// public PasswordEncoder passwordEncoder() {
|
||||
// return new BCryptPasswordEncoder();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 인증 매니저 빈
|
||||
// */
|
||||
// @Bean
|
||||
// public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||
// return config.getAuthenticationManager();
|
||||
// }
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ import java.util.Date;
|
||||
* JWT 토큰 프로바이더 클래스
|
||||
* JWT 토큰 생성, 검증, 파싱 기능을 제공
|
||||
*/
|
||||
@Component("memberJwtTokenProvider") // 기존: @Component
|
||||
@Component("memberJwtTokenProvider")
|
||||
@Slf4j
|
||||
public class JwtTokenProvider {
|
||||
|
||||
@ -25,9 +25,9 @@ public class JwtTokenProvider {
|
||||
private final long accessTokenExpiration;
|
||||
private final long refreshTokenExpiration;
|
||||
|
||||
public JwtTokenProvider(@Value("${jwt.secret}") String secret,
|
||||
@Value("${jwt.access-token-expiration}") long accessTokenExpiration,
|
||||
@Value("${jwt.refresh-token-expiration}") long refreshTokenExpiration) {
|
||||
public JwtTokenProvider(@Value("${jwt.secret:mySecretKey123456789012345678901234567890}") String secret,
|
||||
@Value("${jwt.access-token-expiration:1800000}") long accessTokenExpiration,
|
||||
@Value("${jwt.refresh-token-expiration:604800000}") long refreshTokenExpiration) {
|
||||
this.secretKey = Keys.hmacShaKeyFor(secret.getBytes());
|
||||
this.accessTokenExpiration = accessTokenExpiration;
|
||||
this.refreshTokenExpiration = refreshTokenExpiration;
|
||||
@ -43,6 +43,7 @@ public class JwtTokenProvider {
|
||||
return Jwts.builder()
|
||||
.setSubject(memberId.toString())
|
||||
.claim("role", role)
|
||||
.claim("type", "access")
|
||||
.setIssuedAt(now)
|
||||
.setExpiration(expiration)
|
||||
.signWith(secretKey)
|
||||
@ -58,6 +59,7 @@ public class JwtTokenProvider {
|
||||
|
||||
return Jwts.builder()
|
||||
.setSubject(memberId.toString())
|
||||
.claim("type", "refresh")
|
||||
.setIssuedAt(now)
|
||||
.setExpiration(expiration)
|
||||
.signWith(secretKey)
|
||||
@ -68,47 +70,70 @@ public class JwtTokenProvider {
|
||||
* 토큰에서 인증 정보 추출
|
||||
*/
|
||||
public Authentication getAuthentication(String token) {
|
||||
Claims claims = parseClaims(token);
|
||||
|
||||
Claims claims = getClaims(token);
|
||||
String memberId = claims.getSubject();
|
||||
String role = claims.get("role", String.class);
|
||||
String role = (String) claims.get("role");
|
||||
|
||||
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + (role != null ? role : "USER"));
|
||||
|
||||
return new UsernamePasswordAuthenticationToken(
|
||||
memberId,
|
||||
null,
|
||||
Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + role))
|
||||
Collections.singletonList(authority)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 토큰에서 회원 ID 추출
|
||||
*/
|
||||
public Long getMemberIdFromToken(String token) {
|
||||
Claims claims = parseClaims(token);
|
||||
return Long.valueOf(claims.getSubject());
|
||||
}
|
||||
|
||||
/**
|
||||
* 토큰 유효성 검증
|
||||
*/
|
||||
public boolean validateToken(String token) {
|
||||
try {
|
||||
parseClaims(token);
|
||||
getClaims(token);
|
||||
return true;
|
||||
} catch (JwtException | IllegalArgumentException e) {
|
||||
log.warn("Invalid JWT token: {}", e.getMessage());
|
||||
return false;
|
||||
} catch (ExpiredJwtException e) {
|
||||
log.warn("JWT 토큰 만료: {}", e.getMessage());
|
||||
} catch (UnsupportedJwtException e) {
|
||||
log.warn("지원되지 않는 JWT 토큰: {}", e.getMessage());
|
||||
} catch (MalformedJwtException e) {
|
||||
log.warn("잘못된 형식의 JWT 토큰: {}", e.getMessage());
|
||||
} catch (SecurityException | IllegalArgumentException e) {
|
||||
log.warn("JWT 토큰 검증 실패: {}", e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 토큰 파싱
|
||||
* 토큰에서 회원 ID 추출
|
||||
*/
|
||||
private Claims parseClaims(String token) {
|
||||
public Long getMemberIdFromToken(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return Long.parseLong(claims.getSubject());
|
||||
}
|
||||
|
||||
/**
|
||||
* 토큰에서 클레임 추출
|
||||
*/
|
||||
private Claims getClaims(String token) {
|
||||
return Jwts.parser()
|
||||
.setSigningKey(secretKey)
|
||||
.build()
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 토큰 만료 시간 조회
|
||||
*/
|
||||
public Date getExpirationDateFromToken(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return claims.getExpiration();
|
||||
}
|
||||
|
||||
/**
|
||||
* 토큰이 만료되었는지 확인
|
||||
*/
|
||||
public boolean isTokenExpired(String token) {
|
||||
Date expiration = getExpirationDateFromToken(token);
|
||||
return expiration.before(new Date());
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user