diff --git a/src/main/java/io/company/localhost/common/annotation/Admin.java b/src/main/java/io/company/localhost/common/annotation/Admin.java new file mode 100644 index 0000000..35fc507 --- /dev/null +++ b/src/main/java/io/company/localhost/common/annotation/Admin.java @@ -0,0 +1,11 @@ +package io.company.localhost.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Admin { +} diff --git a/src/main/java/io/company/localhost/common/annotation/Member.java b/src/main/java/io/company/localhost/common/annotation/Member.java new file mode 100644 index 0000000..c435e50 --- /dev/null +++ b/src/main/java/io/company/localhost/common/annotation/Member.java @@ -0,0 +1,11 @@ +package io.company.localhost.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Member { +} diff --git a/src/main/java/io/company/localhost/common/annotation/ReqMap.java b/src/main/java/io/company/localhost/common/annotation/ReqMap.java index 84255dd..87715fb 100644 --- a/src/main/java/io/company/localhost/common/annotation/ReqMap.java +++ b/src/main/java/io/company/localhost/common/annotation/ReqMap.java @@ -1,15 +1,10 @@ package io.company.localhost.common.annotation; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; +import java.lang.annotation.*; @Documented -@Retention(RUNTIME) -@Target({ PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) public @interface ReqMap { } diff --git a/src/main/java/io/company/localhost/common/config/AuthConfig.java b/src/main/java/io/company/localhost/common/security/config/AuthConfig.java similarity index 71% rename from src/main/java/io/company/localhost/common/config/AuthConfig.java rename to src/main/java/io/company/localhost/common/security/config/AuthConfig.java index 4640c94..4b17bf6 100644 --- a/src/main/java/io/company/localhost/common/config/AuthConfig.java +++ b/src/main/java/io/company/localhost/common/security/config/AuthConfig.java @@ -1,14 +1,16 @@ -package io.company.localhost.common.config; - -import java.util.HashMap; -import java.util.Map; +package io.company.localhost.common.security.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.hierarchicalroles.RoleHierarchy; +import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.DelegatingPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import java.util.HashMap; +import java.util.Map; + @Configuration public class AuthConfig { @@ -22,4 +24,9 @@ public class AuthConfig { return delegatingPasswordEncoder; } + + @Bean + public RoleHierarchy roleHierarchy() { + return RoleHierarchyImpl.fromHierarchy("ROLE_ADMIN > ROLE_MEMBER > ROLE_ANONYMOUS"); + } } diff --git a/src/main/java/io/company/localhost/common/config/SecurityConfig.java b/src/main/java/io/company/localhost/common/security/config/SecurityConfig.java similarity index 95% rename from src/main/java/io/company/localhost/common/config/SecurityConfig.java rename to src/main/java/io/company/localhost/common/security/config/SecurityConfig.java index f6a0d5a..84977c4 100644 --- a/src/main/java/io/company/localhost/common/config/SecurityConfig.java +++ b/src/main/java/io/company/localhost/common/security/config/SecurityConfig.java @@ -1,4 +1,4 @@ -package io.company.localhost.common.config; +package io.company.localhost.common.security.config; import io.company.localhost.common.filter.WebCorsFilter; import io.company.localhost.common.security.dsl.RestApiDsl; @@ -45,12 +45,10 @@ public class SecurityConfig { final boolean MAX_SESSION_PRENT = false; // 최대 세션 수 초과 시 로그인 방지 여부 final String REMEMBER = "remember"; // 'remember me' 기능을 위한 키 final String REMEMBER_KEY = "rememberSecretKey"; - final int REMEMBER_TIME = 60 * 60 * 24 * 365; // 'remember me' 기능의 유효기간 (1년) // API 경로 관련 상수 설정 final String SECURITY_BASE_URL = "/api/user"; final String LOGIN_URL = SECURITY_BASE_URL + "/login"; - final String INVALID_URL = SECURITY_BASE_URL + "/login/duplicated-login"; // 보안 필터 체인 설정 @Bean @@ -89,7 +87,6 @@ public class SecurityConfig { .rememberMe(rm -> rm .key(REMEMBER_KEY) - .tokenValiditySeconds(REMEMBER_TIME) .rememberMeParameter(REMEMBER) .rememberMeServices(rememberMeServices())) // 로그인 성공 및 실패 핸들러 설정 diff --git a/src/main/java/io/company/localhost/common/security/handler/RestAuthenticationEntryPointHandler.java b/src/main/java/io/company/localhost/common/security/handler/RestAuthenticationEntryPointHandler.java index 2a24a99..c75b308 100644 --- a/src/main/java/io/company/localhost/common/security/handler/RestAuthenticationEntryPointHandler.java +++ b/src/main/java/io/company/localhost/common/security/handler/RestAuthenticationEntryPointHandler.java @@ -1,17 +1,17 @@ package io.company.localhost.common.security.handler; -import java.io.IOException; - +import com.fasterxml.jackson.databind.ObjectMapper; +import io.company.localhost.common.exception.code.UserErrorCode; +import io.company.localhost.utils.AuthUtil; +import io.company.localhost.vo.MemberVo; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.MediaType; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; -import com.fasterxml.jackson.databind.ObjectMapper; - -import io.company.localhost.common.exception.code.UserErrorCode; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; public class RestAuthenticationEntryPointHandler implements AuthenticationEntryPoint { @@ -21,12 +21,15 @@ public class RestAuthenticationEntryPointHandler implements AuthenticationEntryP public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - // HTTP 상태 코드를 401 (Unauthorized)로 설정 - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - // 응답의 콘텐츠 타입을 JSON으로 설정 response.setContentType(MediaType.APPLICATION_JSON_VALUE); + MemberVo user = AuthUtil.getUser(); - // 사용자 정의 에러 코드와 메시지를 JSON 형식으로 응답 - response.getWriter().write(mapper.writeValueAsString(UserErrorCode.NOT_AUTH_USER.getApiResponse())); + if(user != null) { + response.setStatus(HttpServletResponse.SC_FORBIDDEN); + response.getWriter().write(mapper.writeValueAsString(UserErrorCode.INACTIVE_USER.getApiResponse())); + }else{ + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.getWriter().write(mapper.writeValueAsString(UserErrorCode.NOT_AUTH_USER.getApiResponse())); + } } } diff --git a/src/main/java/io/company/localhost/common/security/manager/CustomDynamicAuthorizationManager.java b/src/main/java/io/company/localhost/common/security/manager/CustomDynamicAuthorizationManager.java index 4932bb7..9e06510 100644 --- a/src/main/java/io/company/localhost/common/security/manager/CustomDynamicAuthorizationManager.java +++ b/src/main/java/io/company/localhost/common/security/manager/CustomDynamicAuthorizationManager.java @@ -1,25 +1,29 @@ package io.company.localhost.common.security.manager; +import io.company.localhost.common.annotation.Admin; import io.company.localhost.common.annotation.Guest; +import io.company.localhost.common.annotation.Member; import io.company.localhost.common.security.mapper.MapBasedUrlRoleMapper; import io.company.localhost.common.security.service.DynamicAuthorizationService; +import io.company.localhost.common.wrapper.RequestMappingWrapper; +import io.company.localhost.utils.ExceptionUtil; import io.company.localhost.vo.MemberVo; import jakarta.annotation.PostConstruct; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; +import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.authorization.AuthorityAuthorizationManager; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.authorization.AuthorizationResult; import org.springframework.security.core.Authentication; +import org.springframework.security.web.access.expression.DefaultHttpSecurityExpressionHandler; import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager; import org.springframework.security.web.access.intercept.RequestAuthorizationContext; import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcherEntry; import org.springframework.stereotype.Component; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.HandlerExecutionChain; import org.springframework.web.servlet.handler.HandlerMappingIntrospector; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @@ -30,10 +34,13 @@ import java.util.stream.Collectors; @Component @RequiredArgsConstructor public class CustomDynamicAuthorizationManager implements AuthorizationManager { + List>> mappings; - private static final AuthorizationDecision DENY = new AuthorizationDecision(false); + private final HandlerMappingIntrospector handlerMappingIntrospector; private final RequestMappingHandlerMapping requestMappingHandlerMapping; + private final RequestMappingWrapper requestMappingWrapper; + private final RoleHierarchy roleHierarchy; // 클래스 초기화 후 동적으로 URL-권한 매핑을 설정 @PostConstruct @@ -51,56 +58,64 @@ public class CustomDynamicAuthorizationManager implements AuthorizationManager authentication, RequestAuthorizationContext object) { HttpServletRequest request = object.getRequest(); - Authentication auth = authentication.get(); - // @Guest 메서드인지 확인 - if (isGuestRequest(request) && !(auth.getPrincipal() instanceof MemberVo)) { - boolean allowGuest = !auth.isAuthenticated() || "anonymousUser".equals(auth.getPrincipal()); - return new AuthorizationDecision(allowGuest); - } - - - for (RequestMatcherEntry> mapping : this.mappings) { - - RequestMatcher matcher = mapping.getRequestMatcher(); - RequestMatcher.MatchResult matchResult = matcher.matcher(object.getRequest()); - - if (matchResult.isMatch()) { - AuthorizationManager manager = mapping.getEntry(); - return manager.authorize(authentication, - new RequestAuthorizationContext(object.getRequest(), matchResult.getVariables())); + try { + if (requestMappingWrapper.hasAnyAnnotation(request, Guest.class) && !(auth.getPrincipal() instanceof MemberVo)) { + boolean allowGuest = !auth.isAuthenticated() || "anonymousUser".equals(auth.getPrincipal()); + return new AuthorizationDecision(allowGuest); + }else if (requestMappingWrapper.hasAnyAnnotation(request, Member.class)) { + boolean isMember = auth.isAuthenticated() && + roleHierarchy.getReachableGrantedAuthorities(auth.getAuthorities()).stream() + .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals("ROLE_MEMBER")); // 수정 + return new AuthorizationDecision(isMember); + }else if (requestMappingWrapper.hasAnyAnnotation(request, Admin.class)) { + boolean isAdmin = auth.isAuthenticated() && + roleHierarchy.getReachableGrantedAuthorities(auth.getAuthorities()).stream() + .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals("ROLE_ADMIN")); // 수정 + return new AuthorizationDecision(isAdmin); } + + for (RequestMatcherEntry> mapping : this.mappings) { + + RequestMatcher matcher = mapping.getRequestMatcher(); + RequestMatcher.MatchResult matchResult = matcher.matcher(object.getRequest()); + + if (matchResult.isMatch()) { + AuthorizationManager manager = mapping.getEntry(); + return manager.authorize(authentication, + new RequestAuthorizationContext(object.getRequest(), matchResult.getVariables())); + } + } + }catch (Exception e){ + ExceptionUtil.messageTrace(e); } - return DENY; + + return new AuthorizationDecision(false); } // 역할에 맞는 AuthorizationManager 반환 private AuthorizationManager customAuthorizationManager(String role) { if (role.startsWith("ROLE")) { - return AuthorityAuthorizationManager.hasAuthority(role); + AuthorityAuthorizationManager objectAuthorityAuthorizationManager = + AuthorityAuthorizationManager.hasAuthority(role); + objectAuthorityAuthorizationManager.setRoleHierarchy(roleHierarchy); + + return objectAuthorityAuthorizationManager; }else{ - return new WebExpressionAuthorizationManager(role); + DefaultHttpSecurityExpressionHandler expressionHandler = new DefaultHttpSecurityExpressionHandler(); + expressionHandler.setRoleHierarchy(roleHierarchy); + + WebExpressionAuthorizationManager webExpressionAuthorizationManager = + new WebExpressionAuthorizationManager(role); + + webExpressionAuthorizationManager.setExpressionHandler(expressionHandler); + + return webExpressionAuthorizationManager; } } - // @Guest가 적용된 요청인지 확인 - private boolean isGuestRequest(HttpServletRequest request) { - try { - HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(request); - - if (handlerExecutionChain != null) { - Object handler = handlerExecutionChain.getHandler(); - if (handler instanceof HandlerMethod handlerMethod) { - return handlerMethod.getMethod().isAnnotationPresent(Guest.class); } - } - } catch (Exception e) { - return false; - } - return false; - } - @Override public void verify(Supplier authentication, RequestAuthorizationContext object) { diff --git a/src/main/java/io/company/localhost/common/security/mapper/MapBasedUrlRoleMapper.java b/src/main/java/io/company/localhost/common/security/mapper/MapBasedUrlRoleMapper.java index 91f7f10..5705b10 100644 --- a/src/main/java/io/company/localhost/common/security/mapper/MapBasedUrlRoleMapper.java +++ b/src/main/java/io/company/localhost/common/security/mapper/MapBasedUrlRoleMapper.java @@ -10,14 +10,11 @@ public class MapBasedUrlRoleMapper implements UrlRoleMapper{ final String PERMIT_ALL = "permitAll"; final String ROLE_MEMBER = "ROLE_MEMBER"; - final String ROLE_MANAGER = "ROLE_MANAGER"; final String ROLE_ADMIN = "ROLE_ADMIN"; @Override public Map getUrlRoleMappings() { - urlRoleMappings.put("/api/login", PERMIT_ALL); urlRoleMappings.put("/api/user/**", ROLE_MEMBER); - urlRoleMappings.put("/api/user/logout", PERMIT_ALL); urlRoleMappings.put("/api/test/**", ROLE_MEMBER); diff --git a/src/main/java/io/company/localhost/common/security/service/CustomRememberMeServices.java b/src/main/java/io/company/localhost/common/security/service/CustomRememberMeServices.java index 040784c..b61f2b1 100644 --- a/src/main/java/io/company/localhost/common/security/service/CustomRememberMeServices.java +++ b/src/main/java/io/company/localhost/common/security/service/CustomRememberMeServices.java @@ -1,32 +1,35 @@ package io.company.localhost.common.security.service; -import static org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.*; - -import java.util.Base64; - -import org.springframework.security.authentication.RememberMeAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.authentication.RememberMeServices; - import io.company.localhost.common.security.details.MemberPrincipalDetails; import io.company.localhost.vo.MemberVo; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.RememberMeAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.RememberMeServices; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Base64; @Slf4j public class CustomRememberMeServices implements RememberMeServices { - private static final String REMEMBER_ME_KEY = "remember"; - private final UserDetailsService userDetailsService; - private final String key; + private static final String REMEMBER_ME_COOKIE_NAME = "remember-me"; + private static final long TOKEN_VALIDITY_SECONDS = 60 * 60 * 24 * 365; // 1 year + private static final String DELIMITER = ":"; - public CustomRememberMeServices(String key, UserDetailsService userDetailsService) { - this.key = key; + private final String secretKey; + private final UserDetailsService userDetailsService; + + public CustomRememberMeServices(String secretKey, UserDetailsService userDetailsService) { + this.secretKey = secretKey; this.userDetailsService = userDetailsService; } @@ -35,26 +38,39 @@ public class CustomRememberMeServices implements RememberMeServices { Cookie rememberMeCookie = getRememberMeCookie(request); if (rememberMeCookie == null) { - log.debug("No remember-me cookie found"); return null; } - String username = decodeCookie(rememberMeCookie.getValue()); - if (username == null || username.isEmpty()) { - log.error("Invalid remember-me cookie"); + String[] tokenParts = decodeAndSplitCookie(rememberMeCookie.getValue()); + if (tokenParts == null || tokenParts.length != 3) { + return null; + } + + String username = tokenParts[0]; + long expiryTime; + try { + expiryTime = Long.parseLong(tokenParts[1]); + } catch (NumberFormatException e) { + return null; + } + + String signature = tokenParts[2]; + if (!isTokenValid(username, expiryTime, signature)) { + return null; + } + + if (System.currentTimeMillis() > expiryTime) { return null; } UserDetails userDetails = userDetailsService.loadUserByUsername(username); - if (userDetails != null) { MemberPrincipalDetails memberDetails = (MemberPrincipalDetails) userDetails; MemberVo memberVo = memberDetails.member(); - RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(key, memberVo, userDetails.getAuthorities()); + RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(secretKey, memberVo, userDetails.getAuthorities()); + auth.setAuthenticated(true); SecurityContextHolder.getContext().setAuthentication(auth); return auth; - }else { - log.error("UserDetailsService returned null for username: {}", username); } return null; @@ -62,58 +78,77 @@ public class CustomRememberMeServices implements RememberMeServices { @Override public void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) { - - Boolean rememberMe = (Boolean) request.getAttribute(REMEMBER_ME_KEY); - if (rememberMe != null && rememberMe) { - // Remember-Me 토큰 생성 및 설정 - Object principal = successfulAuthentication.getPrincipal(); - MemberVo member = (MemberVo)principal; - String username = member.getLoginId(); - String rememberMeToken = generateRememberMeToken(username); - int tokenValiditySeconds = getTokenValiditySeconds(); - - Cookie rememberMeCookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, rememberMeToken); - rememberMeCookie.setPath("/"); - rememberMeCookie.setMaxAge(tokenValiditySeconds); - rememberMeCookie.setHttpOnly(true); - rememberMeCookie.setSecure(request.isSecure()); - response.addCookie(rememberMeCookie); + Object principal = successfulAuthentication.getPrincipal(); + if (!(principal instanceof MemberVo)) { + return; } + + MemberVo member = (MemberVo) principal; + MemberPrincipalDetails details = new MemberPrincipalDetails(member); + String username = member.getLoginId(); + long expiryTime = System.currentTimeMillis() + (TOKEN_VALIDITY_SECONDS * 1000); + String signature = generateSignature(username, expiryTime); + String tokenValue = encodeToken(username, expiryTime, signature); + + + SecurityContextHolder.getContext().setAuthentication(successfulAuthentication); + + Cookie rememberMeCookie = new Cookie(REMEMBER_ME_COOKIE_NAME, tokenValue); + rememberMeCookie.setPath("/"); + rememberMeCookie.setMaxAge((int) TOKEN_VALIDITY_SECONDS); + rememberMeCookie.setHttpOnly(true); + rememberMeCookie.setSecure(request.isSecure()); + response.addCookie(rememberMeCookie); } @Override public void loginFail(HttpServletRequest request, HttpServletResponse response) { - // 로그인 실패 처리 + Cookie cookie = new Cookie(REMEMBER_ME_COOKIE_NAME, null); + cookie.setPath("/"); + cookie.setMaxAge(0); + response.addCookie(cookie); } private Cookie getRememberMeCookie(HttpServletRequest request) { - Cookie[] cookies = request.getCookies(); - if (cookies == null) { + if (request.getCookies() == null) { return null; } - - for(Cookie cookie : cookies) { - if(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY.equals(cookie.getName())) { + for (Cookie cookie : request.getCookies()) { + if (REMEMBER_ME_COOKIE_NAME.equals(cookie.getName())) { return cookie; } } return null; } - private String decodeCookie(String cookieValue) { - try { // Base64 디코딩 - return new String(Base64.getDecoder().decode(cookieValue)); - } catch (IllegalArgumentException e) { + private String[] decodeAndSplitCookie(String cookieValue) { + try { + String decodedValue = new String(Base64.getDecoder().decode(cookieValue), StandardCharsets.UTF_8); + return decodedValue.split(DELIMITER); + } catch (Exception e) { log.error("Failed to decode remember-me cookie", e); return null; } } - private String generateRememberMeToken(String username) { - return Base64.getEncoder().encodeToString(username.getBytes()); + private String encodeToken(String username, long expiryTime, String signature) { + String tokenValue = username + DELIMITER + expiryTime + DELIMITER + signature; + return Base64.getEncoder().encodeToString(tokenValue.getBytes(StandardCharsets.UTF_8)); } - private int getTokenValiditySeconds() { - return 60 * 60 * 24 * 365; + private boolean isTokenValid(String username, long expiryTime, String signature) { + String expectedSignature = generateSignature(username, expiryTime); + return expectedSignature.equals(signature); + } + + private String generateSignature(String username, long expiryTime) { + try { + String data = username + DELIMITER + expiryTime; + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8))); + } catch (Exception e) { + throw new IllegalStateException("Failed to generate signature", e); + } } } diff --git a/src/main/java/io/company/localhost/controller/common/UserController.java b/src/main/java/io/company/localhost/controller/common/UserController.java index 7bb3bf8..dfc5eb8 100644 --- a/src/main/java/io/company/localhost/controller/common/UserController.java +++ b/src/main/java/io/company/localhost/controller/common/UserController.java @@ -1,10 +1,18 @@ package io.company.localhost.controller.common; -import static org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.*; - -import java.util.HashMap; -import java.util.Map; - +import io.company.localhost.common.annotation.Admin; +import io.company.localhost.common.annotation.Guest; +import io.company.localhost.common.annotation.Member; +import io.company.localhost.common.response.ApiResponse; +import io.company.localhost.utils.AuthUtil; +import io.company.localhost.utils.SessionListener; +import io.company.localhost.vo.MemberVo; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -16,16 +24,10 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import io.company.localhost.common.response.ApiResponse; -import io.company.localhost.utils.AuthUtil; -import io.company.localhost.utils.SessionListener; -import io.company.localhost.vo.MemberVo; -import jakarta.servlet.http.Cookie; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.HttpSession; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import java.util.HashMap; +import java.util.Map; + +import static org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY; @Slf4j @RestController @@ -72,7 +74,7 @@ public class UserController { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); boolean remember = false; - if (authentication != null && authentication instanceof RememberMeAuthenticationToken) { + if (authentication instanceof RememberMeAuthenticationToken) { remember = true; } // 쿠키 확인 @@ -94,6 +96,7 @@ public class UserController { //로그아웃 + @Guest @GetMapping("/logout") public ApiResponse logout(HttpServletRequest request, HttpServletResponse response) { String returnMessage = "Successfully logged out"; @@ -117,4 +120,22 @@ public class UserController { } + @Guest + @GetMapping("get1") + public ApiResponse getAuthTest1() { + return ApiResponse.ok(AuthUtil.getUser()); + } + + @Member + @GetMapping("get2") + public ApiResponse getAuthTest2() { + return ApiResponse.ok(AuthUtil.getUser()); + } + + @Admin + @GetMapping("get3") + public ApiResponse getAuthTest3() { + return ApiResponse.ok(AuthUtil.getUser()); + } + }