From 420302fee91fa39fbc1a06b8d2a8c2dddf306703 Mon Sep 17 00:00:00 2001 From: minuk926 Date: Thu, 7 Jul 2022 19:31:33 +0900 Subject: [PATCH] config: config set --- .../com/xit/core/config/WebCommonConfig.java | 6 + .../api/controller/OAuth2LocalController.java | 172 ---------- .../repository/RefreshTokenRepository.java | 10 - .../core/oauth2/api/service/IAuthService.java | 31 -- .../core/oauth2/api/service/IUserService.java | 11 - .../oauth2/api/service/impl/AuthService.java | 311 ------------------ .../oauth2/api/service/impl/UserService.java | 74 ----- .../OAuth2AuthenticationSuccessHandler.java | 1 - .../service/CustomOAuth2UserService.java | 111 ------- .../service/CustomUserDetailsService.java | 25 -- .../xit/core/oauth2/utils/SecurityUtil.java | 4 +- .../java/com/xit/core/util/SpringUtils.java | 9 - 12 files changed, 8 insertions(+), 757 deletions(-) delete mode 100644 src/main/java/com/xit/core/oauth2/api/controller/OAuth2LocalController.java delete mode 100644 src/main/java/com/xit/core/oauth2/api/repository/RefreshTokenRepository.java delete mode 100644 src/main/java/com/xit/core/oauth2/api/service/IAuthService.java delete mode 100644 src/main/java/com/xit/core/oauth2/api/service/IUserService.java delete mode 100644 src/main/java/com/xit/core/oauth2/api/service/impl/AuthService.java delete mode 100644 src/main/java/com/xit/core/oauth2/api/service/impl/UserService.java delete mode 100644 src/main/java/com/xit/core/oauth2/oauth/service/CustomOAuth2UserService.java delete mode 100644 src/main/java/com/xit/core/oauth2/oauth/service/CustomUserDetailsService.java diff --git a/src/main/java/com/xit/core/config/WebCommonConfig.java b/src/main/java/com/xit/core/config/WebCommonConfig.java index faa9725..c2c20ac 100644 --- a/src/main/java/com/xit/core/config/WebCommonConfig.java +++ b/src/main/java/com/xit/core/config/WebCommonConfig.java @@ -6,6 +6,10 @@ import com.xit.core.support.RestTemplateLoggingRequestInterceptor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; @@ -47,6 +51,8 @@ import java.util.concurrent.TimeUnit; @Slf4j @Configuration @EnableSpringDataWebSupport +//@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) +//@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) public class WebCommonConfig extends AsyncConfigurerSupport implements WebMvcConfigurer { private static final String[] EXCLUDE_LOCALE_CHANGE_LIST = { "/resources/**", diff --git a/src/main/java/com/xit/core/oauth2/api/controller/OAuth2LocalController.java b/src/main/java/com/xit/core/oauth2/api/controller/OAuth2LocalController.java deleted file mode 100644 index 908c630..0000000 --- a/src/main/java/com/xit/core/oauth2/api/controller/OAuth2LocalController.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.xit.core.oauth2.api.controller; - -import com.xit.core.api.IRestResponse; -import com.xit.core.api.RestResponse; -import com.xit.core.oauth2.api.dto.LoginRequestDto; -import com.xit.core.oauth2.api.dto.TokenRequestDto; -import com.xit.core.oauth2.api.service.IAuthService; -import com.xit.core.oauth2.oauth.JwtTokenProvider; -//import com.xit.core.support.jpa.EnumFindUtils; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - -@Tag(name = "OAuth2LocalController", description = "인증 관리") -@RestController -@RequestMapping("/api/v1/auth") -@Validated -@RequiredArgsConstructor -public class OAuth2LocalController { - - - private final IAuthService authService; - - - /** - *
-     * 로그인 요청을 처리(Redis에 저장)하고 토큰(Access + Refresh) return
-     *
-     * 1. Login ID, PW 로 인증 정보 객체 UsernamePasswordAuthenticationToken 생성
-     * 2. AuthenticationManager에 authenticate 메소드의 파라미터로 넘겨, 검증 후 Authentication(사용자ID가 들어있다) return
-     *    AuthenticationManager --> 스프링 시큐리티의 실제 인증이 이루어지는 곳
-     *                              authenticate 메소드 하나만 정의되어 있는 인터페이스
-     *                              Builder 에서 UserDetails 의 유저 정보가 서로 일치하는지 검사
-     * 3. 인증정보로 JWT 토큰 생성
-     * 4. Refresh 토큰 저장 : : Redis에 저장
-     * 5. 토큰(Access + Refresh) return
-     * 
- * @see AuthenticationManagerBuilder - * @see JwtTokenProvider - * - * @param loginRequestDto LoginRequestDto - * @param request HttpServletRequest - * @param response HttpServletResponse - * @param session Session - * @return ResponseEntity - */ - @Operation(summary = "login" , description = "login") -// @Parameters({ -// @Parameter(in = ParameterIn.QUERY, name = "providerType", description = "ProviderType", required = true, example = "GOOGLE"), -// @Parameter(in = ParameterIn.QUERY, name = "userId", description = "사용자ID", required = true, example = "minuk926926"), -// @Parameter(in = ParameterIn.QUERY, name = "password", description = "비밀번호", required = true, example = "minuk926926") -// }) - @PostMapping("/login") - public ResponseEntity login( - //@Validated - @Valid - @RequestBody - final LoginRequestDto loginRequestDto, - HttpServletRequest request, - HttpServletResponse response, - HttpSession session - //Errors errors - - ) { - - return RestResponse.of( - authService.login( - loginRequestDto, - request, - response, - session - ) - ); - - } - - /** - *
-     * JWT token 재발급
-     * access token - header, refresh - TokenRequestDto 에 담아 요청
-     *
-     * 1. access token의 유효기간이 남아 있는 경우 ErrorCode.NOT_EXPIRED_TOKEN_YET
-     * 2. refresh token의 유효기간이 재 발급 기준에 부합된 경우 refresh token도 재발급
-     * 3. 2번 항묵에 미 해당시 refresh token 값은 null로
-     * 
- * - * @param tokenRequestDto TokenRequestDto - * @param request HttpServletRequest - * @return ResponseEntity IRestResponse - */ - @Operation(summary = "token 재발급 요청(header & DTO 사용)" , description = "token 재발급 :: accessToken - header, refreshToken - dto") - @Parameter(in = ParameterIn.QUERY, name = "refreshToken", description = "refresh token", required = true, example = " ") - @PostMapping("/jwt/reissue") - public ResponseEntity reissueFromHeader( - @Parameter(hidden = true) - @NotNull - @RequestBody - final TokenRequestDto tokenRequestDto, - HttpServletRequest request) { - return RestResponse.of(authService.reissue(tokenRequestDto, request, null)); - } - - /** - *
-     * JWT token 재발급
-     * access token - header, refresh - cookie 에 담아 요청
-     *
-     * 1. access token의 유효기간이 남아 있는 경우 ErrorCode.NOT_EXPIRED_TOKEN_YET
-     * 2. refresh token의 유효기간이 재 발급 기준에 부합된 경우 refresh token도 재발급
-     * 3. 2번 항묵에 미 해당시 refresh token 값은 null로
-     * 
- * - * @param request HttpServletRequest - * @param response HttpServletResponse - * @return ResponseEntity IRestResponse - */ - @Operation(summary = "token 재발급(header & cookie 사용)" , description = "토큰 재발급 :: accessToken - header, refreshToken - cookie") - //@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "access token", required = true, example = " ") - //@Parameter(in = ParameterIn.COOKIE, name = "refreshToken", description = "refresh token", required = true, example = " ") - @PostMapping("/jwt/reissue/cookie") - public ResponseEntity reissueFromCookie(HttpServletRequest request, HttpServletResponse response) { - return RestResponse.of(authService.reissue(null, request, response)); - } - - - - /** - *
-     * JWT token 재발급
-     * access token - TokenRequestDto, refresh - TokenRequestDto 에 담아 요청
-     *
-     * 1. access token의 유효기간이 남아 있는 경우 ErrorCode.NOT_EXPIRED_TOKEN_YET
-     * 2. refresh token의 유효기간이 재 발급 기준에 부합된 경우 refresh token도 재발급
-     * 3. 2번 항묵에 미 해당시 refresh token 값은 null로
-     * 
- * - * @param tokenRequestDto TokenRequestDto - * @return ResponseEntity IRestResponse - */ - @Operation(summary = "token 재발급(DTO 사용)" , description = "token 재발급 :: accessToken - dto, refreshToken - dto") - @PostMapping("/jwt/reissue/dto") - public ResponseEntity reissueFromParam( - @NotNull - @RequestBody - final TokenRequestDto tokenRequestDto) { - return RestResponse.of(authService.reissue(tokenRequestDto, null, null)); - } - - @Operation(summary = "토큰 체크" , description = "access token 체크") - @PostMapping("/jwt/validate") - public ResponseEntity validate(@RequestParam final String accessToken, @RequestParam boolean isExceptionThrow) { - return RestResponse.of(authService.validationToken(accessToken, isExceptionThrow)); - } - - @Operation(summary = "토큰 정보 확인" , description = "토큰 정보 확인") - @PostMapping("/jwt/info") - public ResponseEntity findAccessTokenInfo(@RequestParam final String accessToken) { - return RestResponse.of(authService.findAccessTokenInfo(accessToken)); - } -} diff --git a/src/main/java/com/xit/core/oauth2/api/repository/RefreshTokenRepository.java b/src/main/java/com/xit/core/oauth2/api/repository/RefreshTokenRepository.java deleted file mode 100644 index a948078..0000000 --- a/src/main/java/com/xit/core/oauth2/api/repository/RefreshTokenRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.xit.core.oauth2.api.repository; - -import com.xit.core.oauth2.api.entity.RefreshToken; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface RefreshTokenRepository extends JpaRepository { - public Optional findByKey(String key); -} diff --git a/src/main/java/com/xit/core/oauth2/api/service/IAuthService.java b/src/main/java/com/xit/core/oauth2/api/service/IAuthService.java deleted file mode 100644 index 4c279b3..0000000 --- a/src/main/java/com/xit/core/oauth2/api/service/IAuthService.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.xit.core.oauth2.api.service; - -import com.xit.biz.cmm.entity.CmmUser; -import com.xit.core.oauth2.api.dto.LoginRequestDto; -import com.xit.core.oauth2.api.dto.TokenDto; -import com.xit.core.oauth2.api.dto.TokenRequestDto; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import java.util.Map; -import java.util.Optional; - -public interface IAuthService { - - //TokenDto login(final CmmUserRequestDto cmmUserRequestDto); - TokenDto login(final LoginRequestDto loginRequestDto, - HttpServletRequest request, - HttpServletResponse response, - HttpSession session); - - TokenDto reissue(final TokenRequestDto tokenRequestDto, HttpServletRequest request, HttpServletResponse response); - - boolean validationToken(final String accessToken, final boolean isExceptionThrow); - - Map findAccessTokenInfo(final String accessToken); - - Optional findMyUserWithoutAuthorities(); - - Optional findUserWithAuthorities(final String userId); -} diff --git a/src/main/java/com/xit/core/oauth2/api/service/IUserService.java b/src/main/java/com/xit/core/oauth2/api/service/IUserService.java deleted file mode 100644 index 913b29b..0000000 --- a/src/main/java/com/xit/core/oauth2/api/service/IUserService.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.xit.core.oauth2.api.service; - -import com.xit.biz.cmm.entity.CmmUser; - -public interface IUserService { - public CmmUser signup(CmmUser cmmUser); - public CmmUser getUser(String userId); - - CmmUser getMemberInfo(String userId); - CmmUser getMyInfo(); -} diff --git a/src/main/java/com/xit/core/oauth2/api/service/impl/AuthService.java b/src/main/java/com/xit/core/oauth2/api/service/impl/AuthService.java deleted file mode 100644 index 04ce0a0..0000000 --- a/src/main/java/com/xit/core/oauth2/api/service/impl/AuthService.java +++ /dev/null @@ -1,311 +0,0 @@ -package com.xit.core.oauth2.api.service.impl; - -import com.xit.core.oauth2.api.entity.RefreshToken; -import com.xit.core.oauth2.api.repository.RefreshTokenRepository; -import com.xit.biz.cmm.entity.CmmUser; -import com.xit.biz.cmm.repository.ICmmUserRepository; -import com.xit.core.constant.ErrorCode; -import com.xit.core.constant.XitConstants; -import com.xit.core.exception.TokenAuthException; -import com.xit.core.oauth2.api.dto.LoginRequestDto; -import com.xit.core.oauth2.api.dto.TokenDto; -import com.xit.core.oauth2.api.dto.TokenRequestDto; -import com.xit.core.oauth2.api.service.IAuthService; -import com.xit.core.oauth2.config.properties.AppProperties; -import com.xit.core.oauth2.oauth.JwtTokenProvider; -import com.xit.core.oauth2.utils.CookieUtil; -import com.xit.core.oauth2.utils.HeaderUtil; -import com.xit.core.util.Checks; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import java.util.*; - -@Service -@RequiredArgsConstructor -public class AuthService implements IAuthService { - @Value("${xit.auth.save.type:header}") - private String authSaveType; - - @Value("${jwt.refresh.save.type:HEADER}") - private String tokenParamType; - - private static final int EXPIRE_CONVERT_SECOND_FROM_DAY = 60 * 60 * 24; - private final static long THREE_DAYS_MILISECONDS = 3 * (1000 * 60 * 60 * 24); - - private final AppProperties appProperties; - private final AuthenticationManager authenticationManager; - private final ICmmUserRepository cmmUserRepository; - private final JwtTokenProvider jwtTokenProvider; - private final RefreshTokenRepository refreshTokenRepository; - - /** - *
-     * 로그인 요청을 처리(Redis에 저장)하고 토큰(Access + Refresh) return
-     *
-     * 1. Login ID, PW 로 인증 정보 객체 UsernamePasswordAuthenticationToken 생성
-     * 2. AuthenticationManager에 authenticate 메소드의 파라미터로 넘겨, 검증 후 Authentication(사용자ID가 들어있다) return
-     *    AuthenticationManager --> 스프링 시큐리티의 실제 인증이 이루어지는 곳
-     *                              authenticate 메소드 하나만 정의되어 있는 인터페이스
-     *                              Builder 에서 UserDetails 의 유저 정보가 서로 일치하는지 검사
-     * 3. 인증정보로 JWT 토큰 생성
-     * 4. Refresh 토큰 저장 : : Redis에 저장
-     * 5. 토큰(Access + Refresh) return
-     *
-     * @see AuthenticationManagerBuilder
-     * @see JwtTokenProvider
-     * 
- * @param loginRequestDto LoginRequestDto - * @return TokenDto - */ - @Override - @Transactional - public TokenDto login(final LoginRequestDto loginRequestDto, - HttpServletRequest request, - HttpServletResponse response, - HttpSession session) { - TokenDto tokenDto = null; - Authentication authentication = null; - - // 1. Login ID/PW 를 기반으로 AuthenticationToken 생성 - UsernamePasswordAuthenticationToken authenticationToken = loginRequestDto.toAuthentication(); - - // 2. 실제로 검증 (사용자 비밀번호 체크) 이 이루어지는 부분 - authentication = authenticationManager.authenticate(authenticationToken); - - // Authentication 저장 - if(Objects.equals(authSaveType, XitConstants.AuthSaveType.SECURITY.getCode())){ - // TODO :: SessionCreationPolicy.STATELESS 인 경우 사용 불가 - SecurityContextHolder.getContext().setAuthentication(authentication); - - }else if(Objects.equals(authSaveType, XitConstants.AuthSaveType.SESSION.getCode())){ - session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); - } - - CmmUser cmmUser = cmmUserRepository.findByUserId(loginRequestDto.getUserId()).orElseThrow(() -> new UsernameNotFoundException(loginRequestDto.getUserId() + " -> 사용자를 찾을 수 없습니다.")); - Map infoMap = new HashMap<>(); - infoMap.put(XitConstants.JwtToken.TOKEN_USER_NAME.getCode(), cmmUser.getUserName()); - infoMap.put(XitConstants.JwtToken.TOKEN_USER_MAIL.getCode(), cmmUser.getEmail()); - - RefreshToken savedRefreshToken = refreshTokenRepository.findByKey(authentication.getName()) - .orElse(null); - - // 저장된 refresh token not exists - if (Checks.isNull(savedRefreshToken) || Checks.isNull(savedRefreshToken.getValue())) { - // 없는 경우 새로 등록 - tokenDto = jwtTokenProvider.generateTokenDto(authentication, infoMap); - refreshTokenRepository.saveAndFlush( - RefreshToken.builder() - .key(loginRequestDto.getUserId()) - .value(tokenDto.getRefreshToken()) - .build() - - ); - - // 저장된 토큰이 있다 - } else { - - // 만료되지 않은 refresh token - if(!jwtTokenProvider.isExpiredToken(savedRefreshToken.getValue())) { - - // refresh token 잔여기간 기준 도달여부 check - Date now = new Date(); - long validTime = jwtTokenProvider.parseClaims(savedRefreshToken.getValue()).getExpiration().getTime() - now.getTime(); - - if (validTime <= THREE_DAYS_MILISECONDS) { - // 새로운 토큰 생성 : access token and refresh token - tokenDto = jwtTokenProvider.generateTokenDto(authentication, infoMap); - - // DB에 refresh 토큰 업데이트 - savedRefreshToken.updateValue(Objects.requireNonNull(tokenDto.getRefreshToken())); - - }else{ - tokenDto = TokenDto.builder() - .grantType(XitConstants.JwtToken.GRANT_TYPE.getCode()) - .accessToken(jwtTokenProvider.generateJwtAccessToken(authentication, infoMap)) - .refreshToken(null) - .build(); - - refreshTokenRepository.saveAndFlush( - RefreshToken.builder() - .key(loginRequestDto.getUserId()) - .value(tokenDto.getRefreshToken()) - .build() - ); - } - - // refresh token 만료 - }else{ - tokenDto = jwtTokenProvider.generateTokenDto(authentication, infoMap); - - refreshTokenRepository.saveAndFlush( - RefreshToken.builder() - .key(loginRequestDto.getUserId()) - .value(tokenDto.getRefreshToken()) - .build() - ); - } - } - - // COOKIE 타입의 요청인 경우 COOKIE set - if(Objects.equals(XitConstants.JwtTokenParamType.COOKIE.name(), tokenParamType)) { - CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()); - CookieUtil.addCookie(response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode(), tokenDto.getRefreshToken(), appProperties.getAuth().getRefreshTokenExpiry() * EXPIRE_CONVERT_SECOND_FROM_DAY); - } - - // 5. 토큰 발급 - return tokenDto; - } - - /** - *
-     * 토큰 재발급 : Redis에 저장
-     * 1. Access 토큰 검증
-     * 2. Access Token 복호화 --> 유저 정보 (Member ID) GET
-     * 3. Refresh Token 만료 여부 검증
-     * 4. 저장소의 Refresh Token GET
-     * 5. 저장소의 Refresh Token == 전달받은 Refresh Token 의 일치 여부 확인
-     * 6. 토큰 생성
-     * 7. Refresh Token update & 저장소 저장
-     * 8. 토큰 return
-     *
-     * @see JwtTokenProvider
-     * 
- * @param tokenRequestDto TokenRequestDto - * @return TokenDto - */ - @Override - @Transactional - public TokenDto reissue(final TokenRequestDto tokenRequestDto, HttpServletRequest request, HttpServletResponse response) { - TokenDto tokenDto = new TokenDto(); - String sAccessToken = null; - String sRefreshToken = null; - Authentication authentication = null; - - //------------------------------------------------------- - // access token 검증 - //------------------------------------------------------- - // Get access token ------------------------------------- - if(Objects.equals(XitConstants.JwtTokenParamType.DTO.name(), tokenParamType)) - sAccessToken = tokenRequestDto.getAccessToken(); - - else if( - Objects.nonNull(request) && - (Objects.equals(XitConstants.JwtTokenParamType.COOKIE.name(), tokenParamType) - || Objects.equals(XitConstants.JwtTokenParamType.HEADER.name(), tokenParamType)) - ) - sAccessToken = HeaderUtil.getAccessToken(request); - else - throw new TokenAuthException("Token 전달 형태가 미 정의 되었습니다."); - - // Access token check ------------------------------------- - // 오염된 토큰 인지만 체크 - jwtTokenProvider.validateTokenExcludeExpired(sAccessToken, false, true); - //if(!jwtTokenProvider.validateToken(sAccessToken, false, false)) throw new TokenAuthException(ErrorCode.INVALID_TOKEN); - // expired access token 여부 체크 - // TODO :: 유효기간 만료된 경우에만 재발급 - 테스트를 위해 반대로 발급되도록 함 - if(jwtTokenProvider.isExpiredToken(sAccessToken)) throw new TokenAuthException(ErrorCode.NOT_EXPIRED_TOKEN_YET); - // -------------------------------------------------------- - - authentication = jwtTokenProvider.getAuthentication(sAccessToken); - - //--------------------------------------------------------- - // refresh token 검증 - //--------------------------------------------------------- - // Get refresh token -------------------------------------- - if(Objects.equals(XitConstants.JwtTokenParamType.COOKIE.name(), tokenParamType)) - sRefreshToken = CookieUtil.getCookie(request, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()) - .map(Cookie::getValue) - .orElse((null)); - else if(Objects.equals(XitConstants.JwtTokenParamType.HEADER.name(), tokenParamType) - || Objects.equals(XitConstants.JwtTokenParamType.DTO.name(), tokenParamType)) - sRefreshToken = tokenRequestDto.getRefreshToken(); - - // Refresh token check ------------------------------------ - jwtTokenProvider.validateTokenExcludeExpired(sRefreshToken, true, true); - - // userId refresh token 으로 DB 확인 - RefreshToken savedRefreshToken = refreshTokenRepository.findByKey(authentication.getName()) - .orElse(null); - if (Checks.isEmpty(savedRefreshToken)) throw new TokenAuthException(ErrorCode.NOT_EXISTS_SAVED_REFRESH_TOKEN); - - if (!Objects.equals(Objects.requireNonNull(savedRefreshToken).getValue(), sRefreshToken)) { - throw new TokenAuthException(ErrorCode.MISMATCH_REFRESH_ACCESS_TOKEN); - } - - // 토큰 부가 정보 set - CmmUser cmmUser = cmmUserRepository.findByUserId(authentication.getName()).orElse(null); - if(Checks.isNull(cmmUser)) throw new TokenAuthException(ErrorCode.INVALID_ROLE_TOKEN); - Map infoMap = new HashMap<>(); - infoMap.put(XitConstants.JwtToken.TOKEN_USER_NAME.getCode(), cmmUser.getUserName()); - infoMap.put(XitConstants.JwtToken.TOKEN_USER_MAIL.getCode(), cmmUser.getEmail()); - - // TODO : refresh토큰 발급 기준인 정의 필요 - // refresh 토큰 기간이 3일 이하로 남은 경우, refresh 토큰 갱신 - Date now = new Date(); - long validTime = jwtTokenProvider.parseClaims(sRefreshToken).getExpiration().getTime() - now.getTime(); - - if (validTime <= THREE_DAYS_MILISECONDS) { - // 토큰 생성 : access token and refresh token - tokenDto = jwtTokenProvider.generateTokenDto(authentication, infoMap); - - // TODO : DB 갱신 확인 필요 - // DB refresh 토큰 업데이트 - RefreshToken newRefreshToken = savedRefreshToken.updateValue(Objects.requireNonNull(tokenDto.getRefreshToken())); - //refreshTokenRepository.saveAndFlush(newRefreshToken); - - if(Objects.equals(XitConstants.JwtTokenParamType.COOKIE.name(), tokenParamType)) { - CookieUtil.deleteCookie(request, response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode()); - CookieUtil.addCookie(response, XitConstants.JwtToken.REFRESH_TOKEN_NAME.getCode(), newRefreshToken.getValue(), appProperties.getAuth().getRefreshTokenExpiry() * EXPIRE_CONVERT_SECOND_FROM_DAY); - } - - }else{ - tokenDto = TokenDto.builder() - .grantType(XitConstants.JwtToken.GRANT_TYPE.getCode()) - .accessToken(jwtTokenProvider.generateJwtAccessToken(authentication, infoMap)) - .refreshToken(null) - .build(); - } - return tokenDto; - } - - @Override - @Transactional(readOnly = true) - public boolean validationToken(final String accessToken, final boolean isExceptionThrow) { - return jwtTokenProvider.validateTokenExcludeExpired(accessToken, false, isExceptionThrow); - } - - // TODO :: 적용 필요 - @Override - @Transactional(readOnly = true) - public Map findAccessTokenInfo(String accessToken) { - return jwtTokenProvider.getAccessTokenInfo(accessToken); //authTokenProvider.getAccessTokenInfo(accessToken); - } - - - @Override - @Transactional(readOnly = true) - public Optional findMyUserWithoutAuthorities() { - //cmmUserRepos - return Optional.empty(); //cmmUserRepository.findOneWithAuthorities(SecurityUtil.getCurrentMemberId()); - } - - @Override - @Transactional(readOnly = true) - public Optional findUserWithAuthorities(final String userId) { - return Optional.empty(); //cmmUserRepository.findOneWithAuthorities(userId); - } -} diff --git a/src/main/java/com/xit/core/oauth2/api/service/impl/UserService.java b/src/main/java/com/xit/core/oauth2/api/service/impl/UserService.java deleted file mode 100644 index 2f6cd9c..0000000 --- a/src/main/java/com/xit/core/oauth2/api/service/impl/UserService.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.xit.core.oauth2.api.service.impl; - -import com.xit.biz.cmm.entity.CmmUser; -import com.xit.biz.cmm.repository.ICmmUserRepository; -import com.xit.core.constant.ErrorCode; -import com.xit.core.exception.AuthorizationException; -import com.xit.core.exception.CustomBaseException; -import com.xit.core.exception.UserExistedException; -import com.xit.core.oauth2.api.service.IUserService; -import com.xit.core.oauth2.oauth.entity.ProviderType; -import com.xit.core.oauth2.oauth.entity.RoleType; -import com.xit.core.oauth2.utils.SecurityUtil; -import com.xit.core.util.CommUtil; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Objects; -import java.util.UUID; - -@Service -@RequiredArgsConstructor -public class UserService implements IUserService { - @Value("${xit.auth.save.type:header}") - private String authSaveType; - - private final ICmmUserRepository cmmUserRepository; - private final PasswordEncoder passwordEncoder; - - /** - * 회원 정보 저장 - * - * @param cmmUser CmmUser - * @return CmmUser - */ - @Transactional - public CmmUser signup(CmmUser cmmUser) { - //if (cmmUserRepository.findByUserId(cmmUser.getUserId()).isPresent()) { - if (cmmUserRepository.existsByUserId(cmmUser.getUserId())) { - throw new UserExistedException(ErrorCode.MEMBER_EXISTS); - } - cmmUser.setCmmUserId(CommUtil.getStringFromUUID()); - cmmUser.setCreatedBy(cmmUser.getUserId()); - //cmmUser.setCreatedDate(LocalDateTime.now()); - cmmUser.setRoleType(RoleType.USER); - - if (Objects.equals(ProviderType.LOCAL, cmmUser.getProviderType())) { - cmmUser.setPassword(passwordEncoder.encode(cmmUser.getPassword())); - } else { - cmmUser.setPassword("NO_PASSWORD"); - //cmmUser.setProviderType(cmmUser.getUserId()); - } - return cmmUserRepository.save(cmmUser); - } - - public CmmUser getUser(String userId) { - return cmmUserRepository.findByUserId(userId).orElseThrow(() -> new CustomBaseException(ErrorCode.USER_NOT_FOUND)); - } - - - @Transactional(readOnly = true) - public CmmUser getMemberInfo(String userId) { - return cmmUserRepository.findByUserId(userId).orElseThrow(() -> new CustomBaseException(ErrorCode.USER_NOT_FOUND)); - } - - // 현재 SecurityContext 에 있는 유저 정보 가져오기 - @Transactional(readOnly = true) - public CmmUser getMyInfo() { - String userId = SecurityUtil.getCurrentUserId(authSaveType); - return cmmUserRepository.findByUserId(userId).orElseThrow(() -> new AuthorizationException(ErrorCode.USER_NOT_FOUND)); - } -} diff --git a/src/main/java/com/xit/core/oauth2/oauth/handler/OAuth2AuthenticationSuccessHandler.java b/src/main/java/com/xit/core/oauth2/oauth/handler/OAuth2AuthenticationSuccessHandler.java index 9c7f9d7..1d723ed 100644 --- a/src/main/java/com/xit/core/oauth2/oauth/handler/OAuth2AuthenticationSuccessHandler.java +++ b/src/main/java/com/xit/core/oauth2/oauth/handler/OAuth2AuthenticationSuccessHandler.java @@ -2,7 +2,6 @@ package com.xit.core.oauth2.oauth.handler; import com.xit.core.oauth2.api.dao.RefreshTokenDao; import com.xit.core.oauth2.api.entity.RefreshToken; -import com.xit.core.oauth2.api.repository.RefreshTokenRepository; import com.xit.core.constant.XitConstants; import com.xit.core.oauth2.config.properties.AppProperties; import com.xit.core.oauth2.oauth.entity.ProviderType; diff --git a/src/main/java/com/xit/core/oauth2/oauth/service/CustomOAuth2UserService.java b/src/main/java/com/xit/core/oauth2/oauth/service/CustomOAuth2UserService.java deleted file mode 100644 index 068b60f..0000000 --- a/src/main/java/com/xit/core/oauth2/oauth/service/CustomOAuth2UserService.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.xit.core.oauth2.oauth.service; - -import com.xit.biz.cmm.entity.CmmUser; -import com.xit.biz.cmm.repository.ICmmUserRepository; -import com.xit.core.oauth2.oauth.entity.ProviderType; -import com.xit.core.oauth2.oauth.entity.RoleType; -import com.xit.core.oauth2.oauth.entity.UserPrincipal; -import com.xit.core.oauth2.oauth.exception.OAuthProviderMissMatchException; -import com.xit.core.oauth2.oauth.info.AbstractOAuth2UserInfo; -import com.xit.core.oauth2.oauth.info.OAuth2UserInfoFactory; -import com.xit.core.util.CommUtil; -import lombok.RequiredArgsConstructor; -import org.springframework.security.authentication.InternalAuthenticationServiceException; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.stereotype.Service; - -import java.time.LocalDateTime; -import java.util.Objects; -import java.util.Optional; - -@Service -@RequiredArgsConstructor -public class CustomOAuth2UserService extends DefaultOAuth2UserService { - - private final ICmmUserRepository userRepository; - - @Override - public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { - OAuth2User user = super.loadUser(userRequest); - - try { - return this.process(userRequest, user); - } catch (AuthenticationException ex) { - throw ex; - } catch (Exception ex) { - ex.printStackTrace(); - throw new InternalAuthenticationServiceException(ex.getLocalizedMessage(), ex.getCause()); - } - } - - private OAuth2User process(OAuth2UserRequest userRequest, OAuth2User user) { - // TODO :: 적용 여부 파악 필요 - ProviderType providerType = ProviderType.valueOf(userRequest.getClientRegistration().getRegistrationId().toUpperCase()); - - AbstractOAuth2UserInfo userInfo = OAuth2UserInfoFactory.getOAuth2UserInfo(providerType, user.getAttributes()); - CmmUser savedUser = null; - Optional optionalCmmUser = userRepository.findByUserId(userInfo.getId()); - - if(optionalCmmUser.isPresent()) { - savedUser = optionalCmmUser.get(); - if (Objects.equals(providerType, savedUser.getProviderType())) { - throw new OAuthProviderMissMatchException( - "Looks like you're signed up with " + providerType + - " account. Please use your " + savedUser.getProviderType() + " account to login." - ); - } - updateUser(savedUser, userInfo); - - }else{ - savedUser = createUser(userInfo, providerType); - } - -// if (optionalCmmUser.isEmpty()) { -// if (providerType != savedUser.getProviderType()) { -// throw new OAuthProviderMissMatchException( -// "Looks like you're signed up with " + providerType + -// " account. Please use your " + savedUser.getProviderType() + " account to login." -// ); -// } -// updateUser(savedUser, userInfo); -// } else { -// savedUser = createUser(userInfo, providerType); -// } - - return UserPrincipal.create(savedUser, user.getAttributes()); - } - - private CmmUser createUser(AbstractOAuth2UserInfo userInfo, ProviderType providerType) { - CmmUser user = new CmmUser( - userInfo.getId(), - userInfo.getName(), - userInfo.getEmail(), - "Y", - userInfo.getImageUrl(), - providerType, - RoleType.USER - ); - LocalDateTime localDateTime = LocalDateTime.now(); - user.setCmmUserId(CommUtil.getStringFromUUID()); - user.setCreatedBy(userInfo.getId()); - user.setModifiedBy(userInfo.getId()); - user.setCreatedDtm(localDateTime); - user.setModifiedDtm(localDateTime); - - return userRepository.saveAndFlush(user); - } - - private void updateUser(CmmUser user, AbstractOAuth2UserInfo userInfo) { - if (Objects.nonNull(userInfo.getName()) && !Objects.equals(userInfo.getName(), user.getUserName())) { - user.setUserName(userInfo.getName()); - } - - if (Objects.nonNull(userInfo.getImageUrl()) && !Objects.equals(userInfo.getImageUrl(), user.getProfileImageUrl())) { - user.setProfileImageUrl(userInfo.getImageUrl()); - } - } -} diff --git a/src/main/java/com/xit/core/oauth2/oauth/service/CustomUserDetailsService.java b/src/main/java/com/xit/core/oauth2/oauth/service/CustomUserDetailsService.java deleted file mode 100644 index 0922029..0000000 --- a/src/main/java/com/xit/core/oauth2/oauth/service/CustomUserDetailsService.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.xit.core.oauth2.oauth.service; - -import com.xit.biz.cmm.entity.CmmUser; -import com.xit.biz.cmm.repository.ICmmUserRepository; -import com.xit.core.constant.ErrorCode; -import com.xit.core.exception.CustomBaseException; -import com.xit.core.oauth2.oauth.entity.UserPrincipal; -import lombok.RequiredArgsConstructor; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class CustomUserDetailsService implements UserDetailsService { - - private final ICmmUserRepository cmmUserRepository; - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - CmmUser user = cmmUserRepository.findByUserId(username).orElseThrow(() -> new CustomBaseException(ErrorCode.USER_NOT_FOUND)); - return UserPrincipal.create(user); - } -} diff --git a/src/main/java/com/xit/core/oauth2/utils/SecurityUtil.java b/src/main/java/com/xit/core/oauth2/utils/SecurityUtil.java index 5163ea9..374c8b5 100644 --- a/src/main/java/com/xit/core/oauth2/utils/SecurityUtil.java +++ b/src/main/java/com/xit/core/oauth2/utils/SecurityUtil.java @@ -3,7 +3,7 @@ package com.xit.core.oauth2.utils; import com.xit.core.constant.ErrorCode; import com.xit.core.constant.XitConstants.AuthSaveType; import com.xit.core.exception.UserAuthException; -import com.xit.core.oauth2.api.controller.OAuth2LocalController; +//import com.xit.core.oauth2.api.controller.OAuth2LocalController; import com.xit.core.oauth2.oauth.JwtTokenProvider; import com.xit.core.util.Checks; import lombok.extern.slf4j.Slf4j; @@ -30,7 +30,7 @@ public class SecurityUtil { private SecurityUtil() { } /** - * @see OAuth2LocalController#login + * OAuth2LocalController#login * @return String */ // SecurityContext 에 유저 정보가 저장되는 시점 diff --git a/src/main/java/com/xit/core/util/SpringUtils.java b/src/main/java/com/xit/core/util/SpringUtils.java index 19d3e10..d01acf0 100644 --- a/src/main/java/com/xit/core/util/SpringUtils.java +++ b/src/main/java/com/xit/core/util/SpringUtils.java @@ -1,8 +1,6 @@ package com.xit.core.util; import com.xit.core.config.support.ApplicationContextProvider; -import com.xit.core.oauth2.api.service.IAuthService; -import com.xit.core.oauth2.api.service.impl.AuthService; import com.xit.core.oauth2.oauth.JwtTokenProvider; import org.springframework.context.ApplicationContext; import org.springframework.context.support.MessageSourceAccessor; @@ -44,13 +42,6 @@ public class SpringUtils { // return (CacheService)getBean(CacheService.class); // } - /** - * - * @return IAuthService AuthService - */ - public static IAuthService getAuthService(){ - return (IAuthService)getBean(AuthService.class); - } /** *