From da5903e3d4a26667dcdae8d3b3efc873da3a5764 Mon Sep 17 00:00:00 2001 From: singsangssong Date: Fri, 15 Nov 2024 19:56:31 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8A=B9=EC=9D=B8=EB=AA=BB=EB=B0=9B=EC=9D=80?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B5=AC=EB=B6=84=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/ExceptionMapper.java | 8 ++-- .../kr/tgwing/tech/config/TestDataLoader.java | 15 ++++++- .../tech/security/config/SecurityConfig.java | 40 +++---------------- .../tech/security/filter/LoginFilter.java | 29 ++++++++++++-- .../service/CustomUserDetailsService.java | 5 ++- .../exception/NotAssignmentException.java | 6 +++ .../user/repository/TempUserRepository.java | 3 +- 7 files changed, 58 insertions(+), 48 deletions(-) create mode 100644 src/main/java/kr/tgwing/tech/user/exception/NotAssignmentException.java diff --git a/src/main/java/kr/tgwing/tech/common/exception/ExceptionMapper.java b/src/main/java/kr/tgwing/tech/common/exception/ExceptionMapper.java index b2ea68d..5e6efa4 100644 --- a/src/main/java/kr/tgwing/tech/common/exception/ExceptionMapper.java +++ b/src/main/java/kr/tgwing/tech/common/exception/ExceptionMapper.java @@ -3,6 +3,7 @@ import java.util.LinkedHashMap; import java.util.Map; +import kr.tgwing.tech.user.exception.*; import org.springframework.http.HttpStatus; import kr.tgwing.tech.blog.exception.post.InappropriateUserPostRelationException; @@ -16,11 +17,6 @@ import kr.tgwing.tech.blog.exception.reply.ReplyForbiddenException; import kr.tgwing.tech.blog.exception.reply.ReplyNotFoundException; import kr.tgwing.tech.project.exception.ProjectNotFoundException; -import kr.tgwing.tech.user.exception.EmailCodeException; -import kr.tgwing.tech.user.exception.MessageException; -import kr.tgwing.tech.user.exception.PasswordException; -import kr.tgwing.tech.user.exception.UserDuplicatedException; -import kr.tgwing.tech.user.exception.UserNotFoundException; public class ExceptionMapper { // 예외 객체 -> 예외 상태로 바꿔주는 mapper @@ -45,6 +41,8 @@ private static void setUpUserException() { ExceptionSituation.of("메일에서 에러가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR, 1003)); mapper.put(EmailCodeException.class, ExceptionSituation.of("인증번호가 서로 인치하지 않습니다.", HttpStatus.CONFLICT, 1004)); + mapper.put(NotAssignmentException.class, + ExceptionSituation.of("사용자가 승인되지 않았습니다.", HttpStatus.UNAUTHORIZED, 1005)); } private static void setUpPostException() { diff --git a/src/main/java/kr/tgwing/tech/config/TestDataLoader.java b/src/main/java/kr/tgwing/tech/config/TestDataLoader.java index 7640ac5..d140465 100644 --- a/src/main/java/kr/tgwing/tech/config/TestDataLoader.java +++ b/src/main/java/kr/tgwing/tech/config/TestDataLoader.java @@ -3,6 +3,8 @@ import java.time.LocalDate; import java.util.ArrayList; +import kr.tgwing.tech.user.entity.TempUser; +import kr.tgwing.tech.user.repository.TempUserRepository; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,9 +45,19 @@ public CommandLineRunner loadTestData(PostRepository postRepository, ReplyRepository replyRepository, ProjectRepository projectRepository, ParticipantRepository participantRepository, - LinkRepository linkRepository + LinkRepository linkRepository, + TempUserRepository tempUserRepository ) { return args -> { + TempUser assignment = TempUser.builder() + .studentNumber("2020202020") + .phoneNumber("01000000000") + .email("helloworld@khu.ac.kr") + .name("동아리원") + .password("1234") + .birth(LocalDate.parse("1999-01-01")) + .build(); + User writer1 = User.builder() .studentNumber("2018000000") .phoneNumber("01000000000") @@ -80,6 +92,7 @@ public CommandLineRunner loadTestData(PostRepository postRepository, userRepository.save(writer1); userRepository.save(writer2); userRepository.save(admin); + tempUserRepository.save(assignment); Post post1 = Post.builder() .title("sample blog 1") diff --git a/src/main/java/kr/tgwing/tech/security/config/SecurityConfig.java b/src/main/java/kr/tgwing/tech/security/config/SecurityConfig.java index 2da80f0..2fecd6f 100644 --- a/src/main/java/kr/tgwing/tech/security/config/SecurityConfig.java +++ b/src/main/java/kr/tgwing/tech/security/config/SecurityConfig.java @@ -6,6 +6,7 @@ import kr.tgwing.tech.security.service.JwtBlackListService; import kr.tgwing.tech.security.util.JwtUtil; import kr.tgwing.tech.security.filter.LoginFilter; +import kr.tgwing.tech.user.repository.TempUserRepository; import lombok.extern.log4j.Log4j2; import org.springframework.boot.autoconfigure.security.servlet.PathRequest; import org.springframework.context.annotation.Bean; @@ -32,6 +33,7 @@ public class SecurityConfig { private final AuthenticationConfiguration authenticationConfiguration; private final JwtUtil jwtUtil; + private final TempUserRepository tempUserRepository; private static final String[] PERMIT_URL_ARRAY = { /* swagger v2 */ "/v2/api-docs", @@ -54,22 +56,19 @@ public class SecurityConfig { "/api-docs/json/swagger-config", "/api-docs/json" }; - public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JwtUtil jwtUtil, JwtBlackListService jwtBlackListService) { - + public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JwtUtil jwtUtil, TempUserRepository tempUserRepository) { this.authenticationConfiguration = authenticationConfiguration; this.jwtUtil = jwtUtil; + this.tempUserRepository = tempUserRepository; } @Bean public WebSecurityCustomizer webSecurityCustomizer() { - log.info("WebSecurity......................"); - return web -> web.ignoring() .requestMatchers(PathRequest.toStaticResources().atCommonLocations()); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { - return configuration.getAuthenticationManager(); } @Bean @@ -84,7 +83,6 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .httpBasic(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable) // 토큰 사용하기에 csrf 불가능 .cors(AbstractHttpConfigurer::disable) - // .formLogin(Customizer.withDefaults())// -> 로그인 화면 구성되면 사용해야함. .logout((logout) -> logout .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) @@ -94,17 +92,6 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .logoutSuccessHandler(((request, response, authentication) -> { response.setStatus(HttpServletResponse.SC_OK); }))) // 세션 쿠키 삭제 -// .logout((logout) -> ) -// .logoutUrl("/logout") -// .addLogoutHandler((request, response, authentication) -> { -// HttpSession session = request.getSession(); -// if (session != null) { -// session.invalidate(); -// } -// }) -// .logoutSuccessHandler((request, response, authentication) -> { -// response.sendRedirect("/login"); -// }) .authorizeHttpRequests(request -> request .requestMatchers(PERMIT_URL_ARRAY) .permitAll() @@ -116,28 +103,11 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .permitAll() .anyRequest().authenticated()) .addFilterBefore(new JwtFilter(jwtUtil), LoginFilter.class) - .addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil), + .addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil, tempUserRepository), UsernamePasswordAuthenticationFilter.class) .sessionManagement((session) -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .build(); } -// public HttpSecurity logout(Customizer> logoutCustomizer) throws Exception { -// logoutCustomizer.customize(getOrApply(new LogoutConfigurer<>())); -// return HttpSecurity.this; -// } - - // @Bean - // @ConditionalOnMissingBean(UserDetailsService.class) - // InMemoryUserDetailsManager inMemoryUserDetailsManager() { - // User.UserBuilder users = User.withDefaultPasswordEncoder(); - // UserDetails admin = users - // .username("admin") - // .password("admin") - // .roles("ADMIN") - // .build(); - // return new InMemoryUserDetailsManager(admin); - // } - } diff --git a/src/main/java/kr/tgwing/tech/security/filter/LoginFilter.java b/src/main/java/kr/tgwing/tech/security/filter/LoginFilter.java index bc250fb..6091795 100644 --- a/src/main/java/kr/tgwing/tech/security/filter/LoginFilter.java +++ b/src/main/java/kr/tgwing/tech/security/filter/LoginFilter.java @@ -3,8 +3,13 @@ import jakarta.servlet.FilterChain; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import kr.tgwing.tech.common.exception.CommonException; import kr.tgwing.tech.security.service.CustomUserDetails; import kr.tgwing.tech.security.util.JwtUtil; +import kr.tgwing.tech.user.entity.TempUser; +import kr.tgwing.tech.user.exception.NotAssignmentException; +import kr.tgwing.tech.user.exception.UserNotFoundException; +import kr.tgwing.tech.user.repository.TempUserRepository; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -13,17 +18,22 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.Iterator; +import java.util.Optional; public class LoginFilter extends UsernamePasswordAuthenticationFilter { private final AuthenticationManager authenticationManager; private final JwtUtil jwtUtil; + private final TempUserRepository tempUserRepository; - public LoginFilter(AuthenticationManager authenticationManager, JwtUtil jwtUtil) { + public LoginFilter(AuthenticationManager authenticationManager, + JwtUtil jwtUtil, + TempUserRepository tempUserRepository) { this.authenticationManager = authenticationManager; this.jwtUtil = jwtUtil; - + this.tempUserRepository = tempUserRepository; } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) @@ -41,7 +51,10 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ //로그인 성공시 실행하는 메소드 (여기서 JWT를 발급하면 됨) @Override - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException { + protected void successfulAuthentication(HttpServletRequest request, + HttpServletResponse response, + FilterChain chain, + Authentication authentication) throws IOException { //UserDetailsS CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal(); @@ -68,7 +81,15 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR //로그인 실패시 실행하는 메소드 @Override - protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) { + protected void unsuccessfulAuthentication(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException failed) throws IOException { response.setStatus(401); + + Optional tempUser = tempUserRepository.findByStudentNumber(obtainUsername(request)); + if(tempUser.isPresent()) { + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"message\": \"사용자가 아직 승인받지 못했습니다.\"}"); + } } } diff --git a/src/main/java/kr/tgwing/tech/security/service/CustomUserDetailsService.java b/src/main/java/kr/tgwing/tech/security/service/CustomUserDetailsService.java index 6b1c053..2446f50 100644 --- a/src/main/java/kr/tgwing/tech/security/service/CustomUserDetailsService.java +++ b/src/main/java/kr/tgwing/tech/security/service/CustomUserDetailsService.java @@ -1,6 +1,9 @@ package kr.tgwing.tech.security.service; +import jakarta.servlet.http.HttpServletResponse; +import kr.tgwing.tech.user.entity.TempUser; import kr.tgwing.tech.user.entity.User; +import kr.tgwing.tech.user.repository.TempUserRepository; import kr.tgwing.tech.user.repository.UserRepository; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -22,12 +25,10 @@ public UserDetails loadUserByUsername(String studentNumber) throws UsernameNotFo //DB에서 조회 Optional userData = userRepository.findByStudentNumber(studentNumber); - if (userData.isPresent()) { //UserDetails에 담아서 return하면 AutneticationManager가 검증 함 return new CustomUserDetails(userData.get()); } - return null; } } diff --git a/src/main/java/kr/tgwing/tech/user/exception/NotAssignmentException.java b/src/main/java/kr/tgwing/tech/user/exception/NotAssignmentException.java new file mode 100644 index 0000000..ab7e4a4 --- /dev/null +++ b/src/main/java/kr/tgwing/tech/user/exception/NotAssignmentException.java @@ -0,0 +1,6 @@ +package kr.tgwing.tech.user.exception; + +import kr.tgwing.tech.common.exception.CommonException; + +public class NotAssignmentException extends CommonException { +} diff --git a/src/main/java/kr/tgwing/tech/user/repository/TempUserRepository.java b/src/main/java/kr/tgwing/tech/user/repository/TempUserRepository.java index 11e782a..2007934 100644 --- a/src/main/java/kr/tgwing/tech/user/repository/TempUserRepository.java +++ b/src/main/java/kr/tgwing/tech/user/repository/TempUserRepository.java @@ -5,7 +5,8 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import java.awt.print.Pageable; +import java.util.Optional; public interface TempUserRepository extends JpaRepository, JpaSpecificationExecutor { - + Optional findByStudentNumber(String studentNumber); }