로그인 로직 수정중.

cks
강석 최 2023-12-14 18:00:33 +09:00
parent 8acdf81a02
commit 7b85736e39
8 changed files with 68 additions and 31 deletions

View File

@ -45,6 +45,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-validation'
developmentOnly 'org.springframework.boot:spring-boot-devtools'

View File

@ -3,19 +3,25 @@ package com.dbnt.kcscbackend.config.jwt;
import com.dbnt.kcscbackend.auth.entity.UserInfo;
import com.dbnt.kcscbackend.config.egov.EgovProperties;
import com.dbnt.kcscbackend.config.jwt.redis.RefreshToken;
import com.dbnt.kcscbackend.config.jwt.redis.RefreshTokenRepository;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
*
@ -44,9 +50,11 @@ public class EgovJwtTokenUtil implements Serializable{
private static final long serialVersionUID = -5180902194184255251L;
//public static final long JWT_TOKEN_VALIDITY = 24 * 60 * 60; //하루
public static final long JWT_TOKEN_VALIDITY = (long) ((1 * 60 * 60) / 60) * 60; //토큰의 유효시간 설정, 기본 60분
public static final long JWT_ACCESS_TOKEN_VALIDITY = (30); //토큰의 유효시간 설정, 기본 60분 60*60
public static final String SECRET_KEY = EgovProperties.getProperty("Globals.jwt.secret");
@Autowired
private RefreshTokenRepository refreshTokenRepository;
//retrieve username from jwt token
public String getUserIdFromToken(String token) {
@ -74,17 +82,12 @@ public class EgovJwtTokenUtil implements Serializable{
}
//generate token for user
public String generateToken(UserInfo loginVO) {
return doGenerateToken(loginVO);
}
//while creating the token -
//1. Define claims of the token, like Issuer, Expiration, Subject, and the ID
//2. Sign the JWT using the HS512 algorithm and secret key.
//3. According to JWS Compact Serialization(https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-3.1)
// compaction of the JWT to a URL-safe string
private String doGenerateToken(UserInfo loginVO) {
public String generateAccessToken(UserInfo loginVO) {
Map<String, Object> claims = new HashMap<>();
claims.put("id", loginVO.getUserId() );
claims.put("userSe", loginVO.getUserSe() );
@ -97,10 +100,18 @@ public class EgovJwtTokenUtil implements Serializable{
.setClaims(claims)
.setSubject("Authorization")
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
.setExpiration(new Date(System.currentTimeMillis() + JWT_ACCESS_TOKEN_VALIDITY * 1000))
.signWith(Keys.hmacShaKeyFor(SECRET_KEY.getBytes(StandardCharsets.UTF_8)), SignatureAlgorithm.HS512);
return builder.compact();
}
@Transactional
public String generateRefreshTokenToken(UserInfo loginVO){
RefreshToken refreshToken = new RefreshToken();
refreshToken.setRefreshToken(UUID.randomUUID().toString());
refreshToken.setUserSeq(loginVO.getUserSeq());
refreshTokenRepository.save(refreshToken);
return refreshToken.getRefreshToken();
}
}

View File

@ -0,0 +1,20 @@
package com.dbnt.kcscbackend.config.jwt.redis;
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
@Builder
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@RedisHash(value="refreshToken", timeToLive = 60) // *60*24*14
public class RefreshToken {
@Id
private String refreshToken;
private Integer userSeq;
}

View File

@ -0,0 +1,8 @@
package com.dbnt.kcscbackend.config.jwt.redis;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface RefreshTokenRepository extends CrudRepository<RefreshToken, String> {
}

View File

@ -2,6 +2,7 @@ package com.dbnt.kcscbackend.config.security;
import com.dbnt.kcscbackend.auth.entity.UserInfo;
import com.dbnt.kcscbackend.config.jwt.EgovJwtTokenUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@ -49,12 +50,14 @@ public class CustomUrlAuthenticationSuccessHandler extends SimpleUrlAuthenticati
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
MediaType jsonMimeType = MediaType.APPLICATION_JSON;
String jwtToken = jwtTokenUtil.generateToken(securityUser);
String refreshToken = jwtTokenUtil.generateRefreshTokenToken(securityUser);
String jwtToken = jwtTokenUtil.generateAccessToken(securityUser);
securityUser.setPassword(null);
securityUser.setUserSeq(null);
HashMap<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("resultCode", "200");
resultMap.put("resultVO", (UserDetails)securityUser);
resultMap.put("refreshToken", refreshToken);
resultMap.put("jToken", jwtToken);
// String userName = jwtTokenUtil.getUserSeFromToken(jwtToken);
response.addHeader("Authorization", "BEARER "+jwtToken);

View File

@ -20,7 +20,7 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Slf4j
public class JsonUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public class JsonAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final String DEFAULT_LOGIN_REQUEST_URL = "/auth/login"; // /login/oauth2/ + ????? 로 오는 요청을 처리할 것이다
private static final String HTTP_METHOD = "POST"; //HTTP 메서드의 방식은 POST 이다.
@ -30,9 +30,9 @@ public class JsonUsernamePasswordAuthenticationFilter extends AbstractAuthentica
private final ObjectMapper objectMapper;
public JsonUsernamePasswordAuthenticationFilter(ObjectMapper objectMapper,
AuthenticationSuccessHandler authenticationSuccessHandler, // 로그인 성공 시 처리할 핸들러
AuthenticationFailureHandler authenticationFailureHandler // 로그인 실패 시 처리할 핸들러
public JsonAuthenticationFilter(ObjectMapper objectMapper,
AuthenticationSuccessHandler authenticationSuccessHandler, // 로그인 성공 시 처리할 핸들러
AuthenticationFailureHandler authenticationFailureHandler // 로그인 실패 시 처리할 핸들러
) {
super(DEFAULT_LOGIN_PATH_REQUEST_MATCHER); // 위에서 설정한 /oauth2/login/* 의 요청에, GET으로 온 요청을 처리하기 위해 설정한다.

View File

@ -1,7 +1,5 @@
package com.dbnt.kcscbackend.config.security;
import com.dbnt.kcscbackend.auth.entity.UserInfo;
import com.dbnt.kcscbackend.auth.service.EgovLoginService;
import com.dbnt.kcscbackend.config.jwt.EgovJwtTokenUtil;
import com.dbnt.kcscbackend.config.jwt.JwtAuthenticationEntryPoint;
import com.dbnt.kcscbackend.config.jwt.JwtAuthenticationFilter;
@ -16,28 +14,20 @@ import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
/**
@ -55,8 +45,6 @@ import java.util.Arrays;
@RequiredArgsConstructor
public class SecurityConfig {
@Autowired
private EgovJwtTokenUtil jwtTokenUtil;
@Resource(name = "loginService")
private UserDetailsService loginService;
private final ObjectMapper objectMapper;
@ -150,10 +138,10 @@ public class SecurityConfig {
}
@Bean
public JsonUsernamePasswordAuthenticationFilter jsonUsernamePasswordAuthenticationFilter() {
JsonUsernamePasswordAuthenticationFilter jsonUsernamePasswordAuthenticationFilter = new JsonUsernamePasswordAuthenticationFilter(objectMapper, new CustomUrlAuthenticationSuccessHandler(), loginFailureHandler());
jsonUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManager());
return jsonUsernamePasswordAuthenticationFilter;
public JsonAuthenticationFilter jsonUsernamePasswordAuthenticationFilter() {
JsonAuthenticationFilter jsonAuthenticationFilter = new JsonAuthenticationFilter(objectMapper, new CustomUrlAuthenticationSuccessHandler(), loginFailureHandler());
jsonAuthenticationFilter.setAuthenticationManager(authenticationManager());
return jsonAuthenticationFilter;
}
@Bean

View File

@ -1,8 +1,14 @@
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
# Page Config
Globals.pageUnit=10
Globals.pageSize=10
#JWT secret key
#JWT
# redisConfig
spring.redis.host=localhost
spring.redis.port=6379
# secret key
Globals.jwt.secret = qWwMroux3QtiIJcPSIZARNTZEBBnWVH0jZ2Lx7tfFChCYi0ViZllo1bekZdiU0B3FRjJI7g90n0ha120dwlz8JZU8rOkmNCe9Uq0