From a3b44f8712a832625c0f7512c0206e1010472134 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 3 Sep 2025 12:15:05 +0900 Subject: [PATCH 1/4] chore: Spring security rest api auth config --- .../auth/controller/AuthController.java | 50 ------------------- .../controller/Oauth2CallbackController.java | 20 -------- .../icebang/auth/dto/AuthRequestWrapper.java | 3 -- .../auth/dto/DefaultRequestWrapper.java | 13 ----- .../gltkorea/icebang/auth/dto/LoginDto.java | 3 -- .../auth/dto/OAuth2RequestWrapper.java | 12 ----- .../auth/dto/Oauth2CallbackContent.java | 7 --- .../gltkorea/icebang/auth/dto/SignUpDto.java | 3 -- .../icebang/auth/provider/AuthProvider.java | 11 ---- .../auth/provider/AuthProviderFactory.java | 44 ---------------- .../auth/provider/DefaultProvider.java | 19 ------- .../auth/provider/OAuth2AuthProvider.java | 9 ---- .../icebang/auth/service/AuthService.java | 13 ----- .../icebang/auth/service/AuthServiceImpl.java | 25 ---------- .../auth/service/state/AuthStateService.java | 9 ---- .../service/state/JwtTokenStateService.java | 15 ------ .../service/state/SessionStateService.java | 15 ------ .../config/security/SecurityConfig.java | 10 +++- .../icebang/domain/user/UserStatus.java | 8 --- .../user/model/UserAccountPrincipal.java | 27 ---------- .../icebang/domain/user/model/Users.java | 7 --- .../service/SecurityAuthenticateAdapter.java | 18 ------- .../domain/user/service/UserAuthService.java | 5 -- 23 files changed, 8 insertions(+), 338 deletions(-) delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/controller/AuthController.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/controller/Oauth2CallbackController.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/AuthRequestWrapper.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/DefaultRequestWrapper.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/LoginDto.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/OAuth2RequestWrapper.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/Oauth2CallbackContent.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/SignUpDto.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/AuthProvider.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/AuthProviderFactory.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/DefaultProvider.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/OAuth2AuthProvider.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/AuthService.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/AuthServiceImpl.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/AuthStateService.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/JwtTokenStateService.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/SessionStateService.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/UserStatus.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/model/UserAccountPrincipal.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/model/Users.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/service/SecurityAuthenticateAdapter.java delete mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/service/UserAuthService.java diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/controller/AuthController.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/controller/AuthController.java deleted file mode 100644 index 1e2f9dae..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/controller/AuthController.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.gltkorea.icebang.auth.controller; - -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.Authentication; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.gltkorea.icebang.auth.dto.DefaultRequestWrapper; -import com.gltkorea.icebang.auth.dto.LoginDto; -import com.gltkorea.icebang.auth.dto.SignUpDto; -import com.gltkorea.icebang.auth.provider.AuthProvider; -import com.gltkorea.icebang.auth.provider.AuthProviderFactory; - -import lombok.RequiredArgsConstructor; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/v0/auth") -public class AuthController { - private final AuthProviderFactory authProviderFactory; - - @PostMapping("/signup") - public ResponseEntity signUp(@RequestBody SignUpDto signUpDto) { - // 1. Wrapper DTO 생성 - DefaultRequestWrapper wrapper = DefaultRequestWrapper.builder().signUpDto(signUpDto).build(); - - // 2. Factory에서 Provider 선택 - @SuppressWarnings("unchecked") - AuthProvider provider = - (AuthProvider) authProviderFactory.getProvider("default"); - - // 3. Provider에 인증 위임 (Provider 내부에서 signUp + login 처리) - Authentication auth = provider.authenticate(wrapper); - - // 4. 결과 반환 - return ResponseEntity.status(201).body(auth); - } - - @PostMapping("/signin") - public ResponseEntity signIn(@RequestBody LoginDto loginDto) { - DefaultRequestWrapper wrapper = DefaultRequestWrapper.builder().loginDto(loginDto).build(); - @SuppressWarnings("unchecked") - AuthProvider provider = - (AuthProvider) authProviderFactory.getProvider("default"); - Authentication auth = provider.authenticate(wrapper); - return ResponseEntity.ok(auth); - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/controller/Oauth2CallbackController.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/controller/Oauth2CallbackController.java deleted file mode 100644 index f21d206a..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/controller/Oauth2CallbackController.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gltkorea.icebang.auth.controller; - -import org.springframework.web.bind.annotation.*; - -import lombok.RequiredArgsConstructor; - -@RestController -@RequestMapping("/v0/oauth2/callback") -@RequiredArgsConstructor -public class Oauth2CallbackController { - - @GetMapping("/kakao") - public void handleKakaoCallback(@RequestParam String code) { - // OAuth2RequestWrapper wrapper = new OAuth2RequestWrapper(new - // Oauth2CallbackContent("kakao", code)); - // OAuth2AuthProvider provider = (OAuth2AuthProvider) - // authProviderFactory.getProvider(providerKey); - // Authentication auth = provider.authenticate(wrapper); - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/AuthRequestWrapper.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/AuthRequestWrapper.java deleted file mode 100644 index 3aac5ee4..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/AuthRequestWrapper.java +++ /dev/null @@ -1,3 +0,0 @@ -package com.gltkorea.icebang.auth.dto; - -public interface AuthRequestWrapper {} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/DefaultRequestWrapper.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/DefaultRequestWrapper.java deleted file mode 100644 index 4c2ebc93..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/DefaultRequestWrapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gltkorea.icebang.auth.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; - -@Builder -@AllArgsConstructor -@Getter -public class DefaultRequestWrapper implements AuthRequestWrapper { - private final LoginDto loginDto; - private final SignUpDto signUpDto; -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/LoginDto.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/LoginDto.java deleted file mode 100644 index 73fda179..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/LoginDto.java +++ /dev/null @@ -1,3 +0,0 @@ -package com.gltkorea.icebang.auth.dto; - -public class LoginDto {} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/OAuth2RequestWrapper.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/OAuth2RequestWrapper.java deleted file mode 100644 index 86e9b5d7..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/OAuth2RequestWrapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.gltkorea.icebang.auth.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -@AllArgsConstructor -public class OAuth2RequestWrapper implements AuthRequestWrapper { - private Oauth2CallbackContent callbackContent; -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/Oauth2CallbackContent.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/Oauth2CallbackContent.java deleted file mode 100644 index d496b534..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/Oauth2CallbackContent.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.gltkorea.icebang.auth.dto; - -public class Oauth2CallbackContent { - private String code; - private String state; - private String provider; -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/SignUpDto.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/SignUpDto.java deleted file mode 100644 index 5dc869fa..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/dto/SignUpDto.java +++ /dev/null @@ -1,3 +0,0 @@ -package com.gltkorea.icebang.auth.dto; - -public class SignUpDto {} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/AuthProvider.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/AuthProvider.java deleted file mode 100644 index 8380e96e..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/AuthProvider.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gltkorea.icebang.auth.provider; - -import org.springframework.security.core.Authentication; - -import com.gltkorea.icebang.auth.dto.AuthRequestWrapper; - -public interface AuthProvider { - boolean supports(T request); - - Authentication authenticate(T request); -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/AuthProviderFactory.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/AuthProviderFactory.java deleted file mode 100644 index 4f41363e..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/AuthProviderFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.gltkorea.icebang.auth.provider; - -import java.util.Map; - -import org.springframework.stereotype.Component; - -import com.gltkorea.icebang.auth.dto.AuthRequestWrapper; - -import lombok.RequiredArgsConstructor; - -@Component -@RequiredArgsConstructor -public class AuthProviderFactory { - - private final Map> providers; - - /** - * providerKey에 해당하는 AuthProvider 반환 - * - * @param providerKey "google", "naver", "default" 등, enum으로 refactoring 필요 - * @return AuthProvider - */ - public AuthProvider getProvider(String providerKey) { - AuthProvider provider = providers.get(providerKey.toLowerCase()); - if (provider == null) { - throw new IllegalArgumentException("Unknown auth provider: " + providerKey); - } - return provider; - } - - /** - * OAuth2 전용 Provider 반환 - * - * @param providerKey OAuth2 provider key - * @return OAuth2AuthProvider - */ - public OAuth2AuthProvider getOAuth2Provider(String providerKey) { - AuthProvider provider = getProvider(providerKey); - if (!(provider instanceof OAuth2AuthProvider oauthProvider)) { - throw new IllegalArgumentException(providerKey + " is not an OAuth2 provider"); - } - return oauthProvider; - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/DefaultProvider.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/DefaultProvider.java deleted file mode 100644 index 40a44c7c..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/DefaultProvider.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.gltkorea.icebang.auth.provider; - -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Component; - -import com.gltkorea.icebang.auth.dto.DefaultRequestWrapper; - -@Component("default") -public class DefaultProvider implements AuthProvider { - @Override - public boolean supports(DefaultRequestWrapper request) { - return false; - } - - @Override - public Authentication authenticate(DefaultRequestWrapper request) { - return null; - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/OAuth2AuthProvider.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/OAuth2AuthProvider.java deleted file mode 100644 index 30be51f4..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/provider/OAuth2AuthProvider.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gltkorea.icebang.auth.provider; - -import org.springframework.security.core.Authentication; - -import com.gltkorea.icebang.auth.dto.OAuth2RequestWrapper; - -public interface OAuth2AuthProvider extends AuthProvider { - Authentication authenticateWithCode(OAuth2RequestWrapper oauthContent); -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/AuthService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/AuthService.java deleted file mode 100644 index 30a2a131..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/AuthService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gltkorea.icebang.auth.service; - -import com.gltkorea.icebang.auth.dto.LoginDto; -import com.gltkorea.icebang.auth.dto.SignUpDto; -import com.gltkorea.icebang.domain.user.model.Users; - -public interface AuthService { - Users signUp(SignUpDto signUpDto); - - Users login(LoginDto loginDto); - - Users loadUser(String identifier); -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/AuthServiceImpl.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/AuthServiceImpl.java deleted file mode 100644 index aa118d2d..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/AuthServiceImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.gltkorea.icebang.auth.service; - -import org.springframework.stereotype.Service; - -import com.gltkorea.icebang.auth.dto.LoginDto; -import com.gltkorea.icebang.auth.dto.SignUpDto; -import com.gltkorea.icebang.domain.user.model.Users; - -@Service -public class AuthServiceImpl implements AuthService { - @Override - public Users signUp(SignUpDto signUpDto) { - return null; - } - - @Override - public Users login(LoginDto loginDto) { - return null; - } - - @Override - public Users loadUser(String identifier) { - return null; - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/AuthStateService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/AuthStateService.java deleted file mode 100644 index c802b309..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/AuthStateService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gltkorea.icebang.auth.service.state; - -import org.springframework.security.core.userdetails.UserDetails; - -public sealed interface AuthStateService permits SessionStateService, JwtTokenStateService { - String create(UserDetails userDetails); - - UserDetails validate(String identifier); -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/JwtTokenStateService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/JwtTokenStateService.java deleted file mode 100644 index 9065820e..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/JwtTokenStateService.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.gltkorea.icebang.auth.service.state; - -import org.springframework.security.core.userdetails.UserDetails; - -public final class JwtTokenStateService implements AuthStateService { - @Override - public String create(UserDetails userDetails) { - return ""; - } - - @Override - public UserDetails validate(String identifier) { - return null; - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/SessionStateService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/SessionStateService.java deleted file mode 100644 index 9bed4d1a..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/auth/service/state/SessionStateService.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.gltkorea.icebang.auth.service.state; - -import org.springframework.security.core.userdetails.UserDetails; - -public final class SessionStateService implements AuthStateService { - @Override - public String create(UserDetails userDetails) { - return ""; - } - - @Override - public UserDetails validate(String identifier) { - return null; - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java b/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java index 8a81b429..76badab9 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java @@ -6,6 +6,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @@ -37,8 +38,13 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .hasRole("USER") .anyRequest() .authenticated()) - .formLogin(form -> form.loginPage("/login").defaultSuccessUrl("/").permitAll()) - .logout(logout -> logout.logoutSuccessUrl("/login").permitAll()) + .formLogin(AbstractHttpConfigurer::disable) + .logout( + logout -> + logout + .logoutUrl("/logout") + .logoutSuccessUrl("/login") + .permitAll()) .build(); } diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/UserStatus.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/UserStatus.java deleted file mode 100644 index b23e47e8..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/UserStatus.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.gltkorea.icebang.domain.user; - -public enum UserStatus { - ONBOARDING, // email, password만 된 경우 - ACTIVE, // 완전히 활성화됨 - SUSPENDED, // 일시 정지 - DELETED // 삭제됨 -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/model/UserAccountPrincipal.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/model/UserAccountPrincipal.java deleted file mode 100644 index abca6682..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/model/UserAccountPrincipal.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.gltkorea.icebang.domain.user.model; - -import java.util.Collection; -import java.util.List; - -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - -import lombok.Builder; - -@Builder -public class UserAccountPrincipal implements UserDetails { - @Override - public Collection getAuthorities() { - return List.of(); - } - - @Override - public String getPassword() { - return ""; - } - - @Override - public String getUsername() { - return ""; - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/model/Users.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/model/Users.java deleted file mode 100644 index ab4d28d1..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/model/Users.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.gltkorea.icebang.domain.user.model; - -import com.gltkorea.icebang.domain.user.UserStatus; - -public class Users { - private UserStatus status; -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/service/SecurityAuthenticateAdapter.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/service/SecurityAuthenticateAdapter.java deleted file mode 100644 index f33f546f..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/service/SecurityAuthenticateAdapter.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.gltkorea.icebang.domain.user.service; - -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; - -import com.gltkorea.icebang.auth.service.AuthService; -import com.gltkorea.icebang.domain.user.model.UserAccountPrincipal; -import com.gltkorea.icebang.domain.user.model.Users; - -public class SecurityAuthenticateAdapter implements UserAuthService { - private AuthService authService; - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - Users user = authService.loadUser(username); - return UserAccountPrincipal.builder().build(); // @TODO users -> userdetail로 - } -} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/service/UserAuthService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/service/UserAuthService.java deleted file mode 100644 index dc8396ee..00000000 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/user/service/UserAuthService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.gltkorea.icebang.domain.user.service; - -import org.springframework.security.core.userdetails.UserDetailsService; - -public interface UserAuthService extends UserDetailsService {} From 7e8b5bb383dccf1972a7a78d6c646689d898a2c4 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 3 Sep 2025 12:57:22 +0900 Subject: [PATCH 2/4] =?UTF-8?q?chore:=20User=20auth=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/security/SecurityConfig.java | 8 ++-- .../auth/controller/AuthController.java | 29 ++++++++++++++ .../domain/auth/dto/AuthCredential.java | 27 +++++++++++++ .../icebang/domain/auth/dto/LoginRequest.java | 9 +++++ .../domain/auth/service/AuthService.java | 24 ++++++++++++ .../auth/service/AuthUserDetailService.java | 38 +++++++++++++++++++ .../com/gltkorea/icebang/entity/Users.java | 11 ++++++ 7 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/controller/AuthController.java create mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/dto/AuthCredential.java create mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/dto/LoginRequest.java create mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthService.java create mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthUserDetailService.java create mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/entity/Users.java diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java b/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java index 76badab9..1280e1a2 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java @@ -31,6 +31,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.authorizeHttpRequests( auth -> auth.requestMatchers(SecurityEndpoints.PUBLIC.getMatchers()) + .permitAll() + .requestMatchers("/auth/login") .permitAll() .requestMatchers(SecurityEndpoints.ADMIN.getMatchers()) .hasRole("ADMIN") @@ -40,11 +42,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .authenticated()) .formLogin(AbstractHttpConfigurer::disable) .logout( - logout -> - logout - .logoutUrl("/logout") - .logoutSuccessUrl("/login") - .permitAll()) + logout -> logout.logoutUrl("/auth/logout").logoutSuccessUrl("/auth/login").permitAll()) .build(); } diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/controller/AuthController.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/controller/AuthController.java new file mode 100644 index 00000000..12873e79 --- /dev/null +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/controller/AuthController.java @@ -0,0 +1,29 @@ +package com.gltkorea.icebang.domain.auth.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.gltkorea.icebang.domain.auth.dto.LoginRequest; +import com.gltkorea.icebang.domain.auth.service.AuthService; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; + +@RequestMapping("/auth") +@RestController +@RequiredArgsConstructor +public class AuthController { + private final AuthService authService; + + @PostMapping("/login") + public ResponseEntity login( + @RequestBody LoginRequest loginRequest, HttpServletRequest request) { + authService.login(loginRequest.getUserName(), loginRequest.getPassword()); + + request.getSession(true); + return ResponseEntity.ok("success"); // @TODO:: 201로 변경 + } +} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/dto/AuthCredential.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/dto/AuthCredential.java new file mode 100644 index 00000000..eeb0cf1b --- /dev/null +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/dto/AuthCredential.java @@ -0,0 +1,27 @@ +package com.gltkorea.icebang.domain.auth.dto; + +import java.util.Collection; +import java.util.List; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import lombok.Data; + +@Data +public class AuthCredential implements UserDetails { + @Override + public Collection getAuthorities() { + return List.of(); + } + + @Override + public String getPassword() { + return ""; + } + + @Override + public String getUsername() { + return ""; + } +} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/dto/LoginRequest.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/dto/LoginRequest.java new file mode 100644 index 00000000..e53385cf --- /dev/null +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/dto/LoginRequest.java @@ -0,0 +1,9 @@ +package com.gltkorea.icebang.domain.auth.dto; + +import lombok.Data; + +@Data +public class LoginRequest { + private String userName; // email + private String password; +} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthService.java new file mode 100644 index 00000000..248805ce --- /dev/null +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthService.java @@ -0,0 +1,24 @@ +package com.gltkorea.icebang.domain.auth.service; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; + +import com.gltkorea.icebang.domain.auth.dto.AuthCredential; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class AuthService { + private final AuthenticationManager authenticationManager; + + public AuthCredential login(String email, String password) { + Authentication auth = + authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken(email, password)); + + return (AuthCredential) auth.getPrincipal(); + } +} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthUserDetailService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthUserDetailService.java new file mode 100644 index 00000000..55e17d41 --- /dev/null +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthUserDetailService.java @@ -0,0 +1,38 @@ +package com.gltkorea.icebang.domain.auth.service; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import com.gltkorea.icebang.domain.auth.dto.AuthCredential; +import com.gltkorea.icebang.mapper.UserMapper; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class AuthUserDetailService implements UserDetailsService { + private final UserMapper userMapper; + + @Override + public AuthCredential loadUserByUsername(String username) throws UsernameNotFoundException { + // 4. MyBatis로 DB에서 사용자+역할+권한 조회 + // 5-1. 사용자가 없으면 예외 발생 //throw new UsernameNotFoundException("User not found: " + email); + + // 5-2. 권한 리스트 생성 + // List authorities = createAuthorities(user); + + // 6. UserPrincipal 생성하여 반환 + throw new RuntimeException("Not implemented"); + } + + private List createAuthorities(Users user) { + List authorities = new ArrayList<>(); + + return authorities; + } +} diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/entity/Users.java b/apps/user-service/src/main/java/com/gltkorea/icebang/entity/Users.java new file mode 100644 index 00000000..2536dfae --- /dev/null +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/entity/Users.java @@ -0,0 +1,11 @@ +package com.gltkorea.icebang.entity; + +import lombok.Data; + +@Data +// @TODO:: 우리 User entity에 맞게 설계 +// @TODO:: 관련 테이블들도 구성해야함 +public class Users { + private String email; + private String password; +} From 4b6f2536371c2b1bb90b2c9904fdf2c13725efa8 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 3 Sep 2025 14:01:17 +0900 Subject: [PATCH 3/4] =?UTF-8?q?chore:=20Role=20enum=20=EC=A0=95=EC=9D=98?= =?UTF-8?q?=20=EB=B0=8F=20=EC=9E=84=EC=8B=9C=20security=20filter=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/security/SecurityConfig.java | 24 +++++-- .../security/endpoints/SecurityEndpoints.java | 15 ++++- .../icebang/domain/auth/enums/Role.java | 62 +++++++++++++++++++ 3 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/enums/Role.java diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java b/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java index 1280e1a2..4a2fff36 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/SecurityConfig.java @@ -32,17 +32,33 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { auth -> auth.requestMatchers(SecurityEndpoints.PUBLIC.getMatchers()) .permitAll() - .requestMatchers("/auth/login") + .requestMatchers("/auth/login", "/auth/logout") .permitAll() - .requestMatchers(SecurityEndpoints.ADMIN.getMatchers()) - .hasRole("ADMIN") + .requestMatchers(SecurityEndpoints.DATA_ADMIN.getMatchers()) + .hasAuthority("SUPER_ADMIN") + .requestMatchers(SecurityEndpoints.DATA_ENGINEER.getMatchers()) + .hasAnyAuthority( + "SUPER_ADMIN", "ADMIN", "SENIOR_DATA_ENGINEER", "DATA_ENGINEER") + .requestMatchers(SecurityEndpoints.ANALYST.getMatchers()) + .hasAnyAuthority( + "SUPER_ADMIN", + "ADMIN", + "SENIOR_DATA_ENGINEER", + "DATA_ENGINEER", + "SENIOR_DATA_ANALYST", + "DATA_ANALYST", + "VIEWER") + .requestMatchers(SecurityEndpoints.OPS.getMatchers()) + .hasAnyAuthority( + "SUPER_ADMIN", "ADMIN", "SENIOR_DATA_ENGINEER", "DATA_ENGINEER") .requestMatchers(SecurityEndpoints.USER.getMatchers()) - .hasRole("USER") + .authenticated() .anyRequest() .authenticated()) .formLogin(AbstractHttpConfigurer::disable) .logout( logout -> logout.logoutUrl("/auth/logout").logoutSuccessUrl("/auth/login").permitAll()) + .csrf(AbstractHttpConfigurer::disable) // API 사용을 위해 CSRF 비활성화 .build(); } diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/endpoints/SecurityEndpoints.java b/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/endpoints/SecurityEndpoints.java index 0a24605f..e2d55727 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/endpoints/SecurityEndpoints.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/config/security/endpoints/SecurityEndpoints.java @@ -4,9 +4,20 @@ public enum SecurityEndpoints { PUBLIC( "/", "/login", "/register", "/api/public/**", "/health", "/css/**", "/js/**", "/images/**"), - ADMIN("/admin/**", "/api/admin/**", "/management/**", "/actuator/**"), + // 데이터 관리 관련 엔드포인트 + DATA_ADMIN("/admin/**", "/api/admin/**", "/management/**", "/actuator/**"), - USER("/user/**", "/api/user/**", "/profile/**", "/dashboard"); + // 데이터 엔지니어 전용 엔드포인트 + DATA_ENGINEER("/api/preprocessing/**", "/api/pipeline/**", "/api/jobs/**"), + + // 분석가 전용 엔드포인트 + ANALYST("/api/analysis/**", "/api/reports/**", "/api/dashboard/**"), + + // 운영 관련 엔드포인트 + OPS("/api/scheduler/**", "/api/monitoring/**"), + + // 일반 사용자 엔드포인트 + USER("/user/**", "/profile/**"); private final String[] patterns; diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/enums/Role.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/enums/Role.java new file mode 100644 index 00000000..147d4f37 --- /dev/null +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/enums/Role.java @@ -0,0 +1,62 @@ +package com.gltkorea.icebang.domain.auth.enums; + +import lombok.Getter; + +@Getter +public enum Role { + // 시스템 관리자 + SUPER_ADMIN("시스템 전체 관리 권한", 100), + ADMIN("관리자 권한 (사용자 관리 제외)", 90), + + // 데이터 처리 담당자 + SENIOR_DATA_ENGINEER("고급 데이터 엔지니어 (파이프라인 설계/수정)", 80), + DATA_ENGINEER("데이터 엔지니어 (전처리 작업 실행)", 70), + + // 품질 관리 + QA_ENGINEER("데이터 품질 검증 담당", 60), + DATA_STEWARD("데이터 거버넌스 관리", 50), + + // 분석가 + SENIOR_DATA_ANALYST("수석 데이터 분석가", 40), + DATA_ANALYST("데이터 분석가", 30), + + // 조회 권한 + VIEWER("읽기 전용 사용자", 20), + GUEST("제한적 조회 권한", 10); + + private final String description; + private final int level; + + private Role(String description, int level) { + this.description = description; + this.level = level; + } + + /** + * 권한 레벨 비교 (현재 역할이 요구 역할보다 높은 권한을 가지는지 확인) + * + * @param requiredRole 요구되는 최소 역할 + * @return 권한이 충분한지 여부 + */ + public boolean hasPermission(Role requiredRole) { + return this.level >= requiredRole.level; + } + + /** + * 관리자 권한 여부 확인 + * + * @return 관리자 권한 보유 여부 + */ + public boolean isAdmin() { + return this.level >= ADMIN.level; + } + + /** + * 데이터 엔지니어 권한 여부 확인 + * + * @return 데이터 엔지니어 권한 보유 여부 + */ + public boolean canExecuteDataProcessing() { + return this.level >= DATA_ENGINEER.level; + } +} From 2e2b9575332ca6b7a7e36a2927f82c829055d861 Mon Sep 17 00:00:00 2001 From: can019 Date: Wed, 3 Sep 2025 14:04:39 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20User=20import=20=EB=AC=B8=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../icebang/domain/auth/service/AuthUserDetailService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthUserDetailService.java b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthUserDetailService.java index 55e17d41..5b6b7dbc 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthUserDetailService.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/domain/auth/service/AuthUserDetailService.java @@ -9,6 +9,7 @@ import org.springframework.stereotype.Service; import com.gltkorea.icebang.domain.auth.dto.AuthCredential; +import com.gltkorea.icebang.entity.Users; import com.gltkorea.icebang.mapper.UserMapper; import lombok.RequiredArgsConstructor;