로그인 로직 수정중.
parent
8acdf81a02
commit
7b85736e39
|
|
@ -45,6 +45,7 @@ dependencies {
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
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-jpa'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-validation'
|
implementation 'org.springframework.boot:spring-boot-starter-validation'
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,25 @@ package com.dbnt.kcscbackend.config.jwt;
|
||||||
|
|
||||||
import com.dbnt.kcscbackend.auth.entity.UserInfo;
|
import com.dbnt.kcscbackend.auth.entity.UserInfo;
|
||||||
import com.dbnt.kcscbackend.config.egov.EgovProperties;
|
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.Claims;
|
||||||
import io.jsonwebtoken.JwtBuilder;
|
import io.jsonwebtoken.JwtBuilder;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
import io.jsonwebtoken.SignatureAlgorithm;
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -44,9 +50,11 @@ public class EgovJwtTokenUtil implements Serializable{
|
||||||
|
|
||||||
private static final long serialVersionUID = -5180902194184255251L;
|
private static final long serialVersionUID = -5180902194184255251L;
|
||||||
//public static final long JWT_TOKEN_VALIDITY = 24 * 60 * 60; //하루
|
//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");
|
public static final String SECRET_KEY = EgovProperties.getProperty("Globals.jwt.secret");
|
||||||
|
@Autowired
|
||||||
|
private RefreshTokenRepository refreshTokenRepository;
|
||||||
|
|
||||||
|
|
||||||
//retrieve username from jwt token
|
//retrieve username from jwt token
|
||||||
public String getUserIdFromToken(String token) {
|
public String getUserIdFromToken(String token) {
|
||||||
|
|
@ -74,17 +82,12 @@ public class EgovJwtTokenUtil implements Serializable{
|
||||||
}
|
}
|
||||||
|
|
||||||
//generate token for user
|
//generate token for user
|
||||||
public String generateToken(UserInfo loginVO) {
|
|
||||||
return doGenerateToken(loginVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
//while creating the token -
|
//while creating the token -
|
||||||
//1. Define claims of the token, like Issuer, Expiration, Subject, and the ID
|
//1. Define claims of the token, like Issuer, Expiration, Subject, and the ID
|
||||||
//2. Sign the JWT using the HS512 algorithm and secret key.
|
//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)
|
//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
|
// 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<>();
|
Map<String, Object> claims = new HashMap<>();
|
||||||
claims.put("id", loginVO.getUserId() );
|
claims.put("id", loginVO.getUserId() );
|
||||||
claims.put("userSe", loginVO.getUserSe() );
|
claims.put("userSe", loginVO.getUserSe() );
|
||||||
|
|
@ -97,10 +100,18 @@ public class EgovJwtTokenUtil implements Serializable{
|
||||||
.setClaims(claims)
|
.setClaims(claims)
|
||||||
.setSubject("Authorization")
|
.setSubject("Authorization")
|
||||||
.setIssuedAt(new Date(System.currentTimeMillis()))
|
.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);
|
.signWith(Keys.hmacShaKeyFor(SECRET_KEY.getBytes(StandardCharsets.UTF_8)), SignatureAlgorithm.HS512);
|
||||||
return builder.compact();
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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> {
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package com.dbnt.kcscbackend.config.security;
|
||||||
|
|
||||||
import com.dbnt.kcscbackend.auth.entity.UserInfo;
|
import com.dbnt.kcscbackend.auth.entity.UserInfo;
|
||||||
import com.dbnt.kcscbackend.config.jwt.EgovJwtTokenUtil;
|
import com.dbnt.kcscbackend.config.jwt.EgovJwtTokenUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||||
|
|
@ -49,12 +50,14 @@ public class CustomUrlAuthenticationSuccessHandler extends SimpleUrlAuthenticati
|
||||||
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
|
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
|
||||||
MediaType jsonMimeType = MediaType.APPLICATION_JSON;
|
MediaType jsonMimeType = MediaType.APPLICATION_JSON;
|
||||||
|
|
||||||
String jwtToken = jwtTokenUtil.generateToken(securityUser);
|
String refreshToken = jwtTokenUtil.generateRefreshTokenToken(securityUser);
|
||||||
|
String jwtToken = jwtTokenUtil.generateAccessToken(securityUser);
|
||||||
securityUser.setPassword(null);
|
securityUser.setPassword(null);
|
||||||
securityUser.setUserSeq(null);
|
securityUser.setUserSeq(null);
|
||||||
HashMap<String, Object> resultMap = new HashMap<String, Object>();
|
HashMap<String, Object> resultMap = new HashMap<String, Object>();
|
||||||
resultMap.put("resultCode", "200");
|
resultMap.put("resultCode", "200");
|
||||||
resultMap.put("resultVO", (UserDetails)securityUser);
|
resultMap.put("resultVO", (UserDetails)securityUser);
|
||||||
|
resultMap.put("refreshToken", refreshToken);
|
||||||
resultMap.put("jToken", jwtToken);
|
resultMap.put("jToken", jwtToken);
|
||||||
// String userName = jwtTokenUtil.getUserSeFromToken(jwtToken);
|
// String userName = jwtTokenUtil.getUserSeFromToken(jwtToken);
|
||||||
response.addHeader("Authorization", "BEARER "+jwtToken);
|
response.addHeader("Authorization", "BEARER "+jwtToken);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
@Slf4j
|
@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 DEFAULT_LOGIN_REQUEST_URL = "/auth/login"; // /login/oauth2/ + ????? 로 오는 요청을 처리할 것이다
|
||||||
private static final String HTTP_METHOD = "POST"; //HTTP 메서드의 방식은 POST 이다.
|
private static final String HTTP_METHOD = "POST"; //HTTP 메서드의 방식은 POST 이다.
|
||||||
|
|
@ -30,9 +30,9 @@ public class JsonUsernamePasswordAuthenticationFilter extends AbstractAuthentica
|
||||||
|
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
public JsonUsernamePasswordAuthenticationFilter(ObjectMapper objectMapper,
|
public JsonAuthenticationFilter(ObjectMapper objectMapper,
|
||||||
AuthenticationSuccessHandler authenticationSuccessHandler, // 로그인 성공 시 처리할 핸들러
|
AuthenticationSuccessHandler authenticationSuccessHandler, // 로그인 성공 시 처리할 핸들러
|
||||||
AuthenticationFailureHandler authenticationFailureHandler // 로그인 실패 시 처리할 핸들러
|
AuthenticationFailureHandler authenticationFailureHandler // 로그인 실패 시 처리할 핸들러
|
||||||
) {
|
) {
|
||||||
|
|
||||||
super(DEFAULT_LOGIN_PATH_REQUEST_MATCHER); // 위에서 설정한 /oauth2/login/* 의 요청에, GET으로 온 요청을 처리하기 위해 설정한다.
|
super(DEFAULT_LOGIN_PATH_REQUEST_MATCHER); // 위에서 설정한 /oauth2/login/* 의 요청에, GET으로 온 요청을 처리하기 위해 설정한다.
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package com.dbnt.kcscbackend.config.security;
|
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.EgovJwtTokenUtil;
|
||||||
import com.dbnt.kcscbackend.config.jwt.JwtAuthenticationEntryPoint;
|
import com.dbnt.kcscbackend.config.jwt.JwtAuthenticationEntryPoint;
|
||||||
import com.dbnt.kcscbackend.config.jwt.JwtAuthenticationFilter;
|
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.authentication.dao.DaoAuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
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.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
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.PasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
||||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
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.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.AntPathRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
|
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.cors.CorsConfigurationSource;
|
import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -55,8 +45,6 @@ import java.util.Arrays;
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private EgovJwtTokenUtil jwtTokenUtil;
|
|
||||||
@Resource(name = "loginService")
|
@Resource(name = "loginService")
|
||||||
private UserDetailsService loginService;
|
private UserDetailsService loginService;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
|
|
@ -150,10 +138,10 @@ public class SecurityConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public JsonUsernamePasswordAuthenticationFilter jsonUsernamePasswordAuthenticationFilter() {
|
public JsonAuthenticationFilter jsonUsernamePasswordAuthenticationFilter() {
|
||||||
JsonUsernamePasswordAuthenticationFilter jsonUsernamePasswordAuthenticationFilter = new JsonUsernamePasswordAuthenticationFilter(objectMapper, new CustomUrlAuthenticationSuccessHandler(), loginFailureHandler());
|
JsonAuthenticationFilter jsonAuthenticationFilter = new JsonAuthenticationFilter(objectMapper, new CustomUrlAuthenticationSuccessHandler(), loginFailureHandler());
|
||||||
jsonUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManager());
|
jsonAuthenticationFilter.setAuthenticationManager(authenticationManager());
|
||||||
return jsonUsernamePasswordAuthenticationFilter;
|
return jsonAuthenticationFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
|
|
||||||
|
|
||||||
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
|
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
|
||||||
|
|
||||||
# Page Config
|
# Page Config
|
||||||
Globals.pageUnit=10
|
Globals.pageUnit=10
|
||||||
Globals.pageSize=10
|
Globals.pageSize=10
|
||||||
|
|
||||||
#JWT secret key
|
#JWT
|
||||||
|
# redisConfig
|
||||||
|
spring.redis.host=localhost
|
||||||
|
spring.redis.port=6379
|
||||||
|
# secret key
|
||||||
Globals.jwt.secret = qWwMroux3QtiIJcPSIZARNTZEBBnWVH0jZ2Lx7tfFChCYi0ViZllo1bekZdiU0B3FRjJI7g90n0ha120dwlz8JZU8rOkmNCe9Uq0
|
Globals.jwt.secret = qWwMroux3QtiIJcPSIZARNTZEBBnWVH0jZ2Lx7tfFChCYi0ViZllo1bekZdiU0B3FRjJI7g90n0ha120dwlz8JZU8rOkmNCe9Uq0
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue