From de080a06d61edbd40cc2bec38711a0790330bd52 Mon Sep 17 00:00:00 2001 From: hylee Date: Tue, 21 May 2024 18:00:07 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EB=B0=8F=20=EB=8B=A8=EC=96=B4=EC=82=AC=EC=A0=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/cmn/config/CustomUserDetails.java | 66 ++ .../cmn/config/CustomUserDetailsService.java | 5 +- .../itn/admin/cmn/config/SecurityConfig.java | 11 +- .../itn/admin/cmn/config/SecurityUtil.java | 19 + .../itn/admin/cmn/config/UserInterceptor.java | 4 + .../mapper/domain/DictionaryVO.java | 2 + .../service/impl/DictionaryServiceImpl.java | 11 + .../itn/admin/itn/user/mapper/UserMapper.java | 6 +- .../admin/itn/user/service/UserService.java | 2 + .../user/service/impl/UserServiceImpl.java | 6 + .../itn/dictionary/DictionaryMapper.xml | 28 +- .../resources/templates/dictionary/list.html | 708 +++++++++--------- src/main/resources/templates/user/list.html | 2 +- 13 files changed, 500 insertions(+), 370 deletions(-) create mode 100644 src/main/java/com/itn/admin/cmn/config/CustomUserDetails.java create mode 100644 src/main/java/com/itn/admin/cmn/config/SecurityUtil.java diff --git a/src/main/java/com/itn/admin/cmn/config/CustomUserDetails.java b/src/main/java/com/itn/admin/cmn/config/CustomUserDetails.java new file mode 100644 index 0000000..a601036 --- /dev/null +++ b/src/main/java/com/itn/admin/cmn/config/CustomUserDetails.java @@ -0,0 +1,66 @@ +package com.itn.admin.cmn.config; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; + +public class CustomUserDetails implements UserDetails { + + private final String username; + private final String password; + private final String userId; + private final String id; + private final Collection authorities; + + public CustomUserDetails(String username, String password, String userId, String id, Collection authorities) { + this.username = username; + this.password = password; + this.userId = userId; + this.id = id; + this.authorities = authorities; + } + + public String getUserId() { + return userId; + } + + public String getId() { + return id; + } + + @Override + public Collection getAuthorities() { + return authorities; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getUsername() { + return username; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } +} diff --git a/src/main/java/com/itn/admin/cmn/config/CustomUserDetailsService.java b/src/main/java/com/itn/admin/cmn/config/CustomUserDetailsService.java index 168ad73..8d8f938 100644 --- a/src/main/java/com/itn/admin/cmn/config/CustomUserDetailsService.java +++ b/src/main/java/com/itn/admin/cmn/config/CustomUserDetailsService.java @@ -3,7 +3,6 @@ package com.itn.admin.cmn.config; import com.itn.admin.itn.user.mapper.UserMapper; import com.itn.admin.itn.user.mapper.domain.UserVO; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -31,7 +30,7 @@ public class CustomUserDetailsService implements UserDetailsService { GrantedAuthority authority = new SimpleGrantedAuthority(user.getRole().name()); Collection authorities = Collections.singletonList(authority); - // User 객체 생성 - return new User(user.getUserId(), user.getPassword(), authorities); + // CustomUserDetails 객체 생성 + return new CustomUserDetails(user.getUserId(), user.getPassword(), user.getUserId(), user.getId(), authorities); } } diff --git a/src/main/java/com/itn/admin/cmn/config/SecurityConfig.java b/src/main/java/com/itn/admin/cmn/config/SecurityConfig.java index 156fba9..3a455d8 100644 --- a/src/main/java/com/itn/admin/cmn/config/SecurityConfig.java +++ b/src/main/java/com/itn/admin/cmn/config/SecurityConfig.java @@ -1,6 +1,7 @@ package com.itn.admin.cmn.config; import com.fasterxml.jackson.databind.ObjectMapper; +import com.itn.admin.itn.user.service.UserService; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; @@ -26,9 +27,11 @@ import java.io.PrintWriter; public class SecurityConfig { private final CustomUserDetailsService customUserDetailsService; + private final UserService userService; - public SecurityConfig(CustomUserDetailsService customUserDetailsService) { + public SecurityConfig(CustomUserDetailsService customUserDetailsService, UserService userService) { this.customUserDetailsService = customUserDetailsService; + this.userService = userService; } @Bean @@ -89,8 +92,10 @@ public class SecurityConfig { public AuthenticationSuccessHandler customAuthenticationSuccessHandler() { return (request, response, authentication) -> { // 디버깅 정보를 콘솔에 출력 - System.out.println("Authentication successful. Username: " + authentication.getName()); - System.out.println("Authorities: " + authentication.getAuthorities()); + CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); + String userId = userDetails.getUserId(); + String id = userDetails.getId(); + userService.loginLog(id); response.setStatus(HttpStatus.OK.value()); response.sendRedirect("/"); }; diff --git a/src/main/java/com/itn/admin/cmn/config/SecurityUtil.java b/src/main/java/com/itn/admin/cmn/config/SecurityUtil.java new file mode 100644 index 0000000..0a46550 --- /dev/null +++ b/src/main/java/com/itn/admin/cmn/config/SecurityUtil.java @@ -0,0 +1,19 @@ +package com.itn.admin.cmn.config; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; + +public class SecurityUtil { + + public static String getCurrentUserId() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + Object principal = authentication.getPrincipal(); + if (principal instanceof CustomUserDetails) { + return ((CustomUserDetails) principal).getId(); + } + } + return null; + } +} diff --git a/src/main/java/com/itn/admin/cmn/config/UserInterceptor.java b/src/main/java/com/itn/admin/cmn/config/UserInterceptor.java index 67a4496..6521615 100644 --- a/src/main/java/com/itn/admin/cmn/config/UserInterceptor.java +++ b/src/main/java/com/itn/admin/cmn/config/UserInterceptor.java @@ -3,12 +3,14 @@ package com.itn.admin.cmn.config; import com.itn.admin.itn.user.mapper.domain.UserVO; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; +@Slf4j public class UserInterceptor implements HandlerInterceptor { @Override @@ -33,6 +35,8 @@ public class UserInterceptor implements HandlerInterceptor { userName = principal.toString(); } + log.info("userId : [{}]",userId.toString()); + log.info("userName : [{}]",userName.toString()); modelAndView.addObject("userId", userId); modelAndView.addObject("userName", userName); } diff --git a/src/main/java/com/itn/admin/itn/dictionary/mapper/domain/DictionaryVO.java b/src/main/java/com/itn/admin/itn/dictionary/mapper/domain/DictionaryVO.java index a354d4b..a412bc0 100644 --- a/src/main/java/com/itn/admin/itn/dictionary/mapper/domain/DictionaryVO.java +++ b/src/main/java/com/itn/admin/itn/dictionary/mapper/domain/DictionaryVO.java @@ -27,6 +27,7 @@ public class DictionaryVO implements Serializable { private static final long serialVersionUID = 1L; private Long id; + private String userId; private String koreanWord; private String englishWord; private String abbreviation; @@ -35,6 +36,7 @@ public class DictionaryVO implements Serializable { private String frstRegisterId; private String frstRegistPnttm; private String lastUpdusrId; + private String lastUpdusrName; private String lastUpdtPnttm; } diff --git a/src/main/java/com/itn/admin/itn/dictionary/service/impl/DictionaryServiceImpl.java b/src/main/java/com/itn/admin/itn/dictionary/service/impl/DictionaryServiceImpl.java index 91735f7..5172bbf 100644 --- a/src/main/java/com/itn/admin/itn/dictionary/service/impl/DictionaryServiceImpl.java +++ b/src/main/java/com/itn/admin/itn/dictionary/service/impl/DictionaryServiceImpl.java @@ -1,5 +1,6 @@ package com.itn.admin.itn.dictionary.service.impl; +import com.itn.admin.cmn.config.SecurityUtil; import com.itn.admin.itn.dictionary.mapper.DictionaryMapper; import com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO; import com.itn.admin.itn.dictionary.service.DictionaryService; @@ -30,6 +31,15 @@ public class DictionaryServiceImpl implements DictionaryService { log.info("Received data for update: [{}]", dictionaryMap); + // 현재 인증된 사용자 정보 가져오기 + String userId = SecurityUtil.getCurrentUserId(); + if (userId == null) { + log.warn("Failed to retrieve current user ID."); + throw new IllegalStateException("Current user ID is not available"); + } + log.info("Updating by user: [{}]", userId); + + Map data = (Map) dictionaryMap.get("data"); log.info("data: [{}]", data); String action = (String) dictionaryMap.get("action"); @@ -46,6 +56,7 @@ public class DictionaryServiceImpl implements DictionaryService { } } else { DictionaryVO dictionaryVO = getSingleDate(dictionaryMap); + dictionaryVO.setUserId(userId); if("edit".equals(action)) { log.info("edit :: data for update: [{}]", dictionaryVO); dictionaryMapper.save(dictionaryVO); diff --git a/src/main/java/com/itn/admin/itn/user/mapper/UserMapper.java b/src/main/java/com/itn/admin/itn/user/mapper/UserMapper.java index b93ec6a..e6032b9 100644 --- a/src/main/java/com/itn/admin/itn/user/mapper/UserMapper.java +++ b/src/main/java/com/itn/admin/itn/user/mapper/UserMapper.java @@ -6,6 +6,7 @@ import com.itn.admin.itn.user.mapper.domain.UserVO; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; import java.util.List; import java.util.stream.Collectors; @@ -14,7 +15,7 @@ import java.util.stream.Collectors; public interface UserMapper { // UserVO save(UserVO userVO); - @Select("SELECT user_id AS userId, user_pw AS password, user_name AS username, role FROM users WHERE user_id = #{userId}") + @Select("SELECT id, user_id AS userId, user_pw AS password, user_name AS username, role FROM users WHERE user_id = #{userId}") UserVO getUserById(String userId); @Select("SELECT id, user_id AS userId, user_pw AS password, user_name AS username, role FROM users WHERE id = #{id}") @@ -37,4 +38,7 @@ public interface UserMapper { List findAll(UserVO userVO); void updateRole(UserVO user); + + @Insert("INSERT INTO login_logs (id, FRST_REGIST_PNTTM) VALUES (#{id}, now())") + void loginLog(String id); } diff --git a/src/main/java/com/itn/admin/itn/user/service/UserService.java b/src/main/java/com/itn/admin/itn/user/service/UserService.java index 73eea58..f333e16 100644 --- a/src/main/java/com/itn/admin/itn/user/service/UserService.java +++ b/src/main/java/com/itn/admin/itn/user/service/UserService.java @@ -14,4 +14,6 @@ public interface UserService { Map getList(UserVO userVO); RestResponse updateRole(String id, Role role); + + void loginLog(String id); } diff --git a/src/main/java/com/itn/admin/itn/user/service/impl/UserServiceImpl.java b/src/main/java/com/itn/admin/itn/user/service/impl/UserServiceImpl.java index 58191e5..d20f483 100644 --- a/src/main/java/com/itn/admin/itn/user/service/impl/UserServiceImpl.java +++ b/src/main/java/com/itn/admin/itn/user/service/impl/UserServiceImpl.java @@ -72,5 +72,11 @@ public class UserServiceImpl implements UserService { .build(); } + @Override + public void loginLog(String id) { + userMapper.loginLog(id); + + } + } diff --git a/src/main/resources/mapper/itn/dictionary/DictionaryMapper.xml b/src/main/resources/mapper/itn/dictionary/DictionaryMapper.xml index 504503c..07f1128 100644 --- a/src/main/resources/mapper/itn/dictionary/DictionaryMapper.xml +++ b/src/main/resources/mapper/itn/dictionary/DictionaryMapper.xml @@ -8,17 +8,20 @@ @@ -41,6 +44,9 @@ IS_ACTIVE = #{isActive}, + + LAST_UPDUSR_ID = #{userId}, + LAST_UPDT_PNTTM = NOW() WHERE id = #{id} diff --git a/src/main/resources/templates/dictionary/list.html b/src/main/resources/templates/dictionary/list.html index 476fe83..fcf8b17 100644 --- a/src/main/resources/templates/dictionary/list.html +++ b/src/main/resources/templates/dictionary/list.html @@ -28,382 +28,388 @@ -
-
+
+
- - - - -
- -
-
-
-
-

단어사전

-
-
- -
-
-
-
- - -
-
-
-
- - -
-
-

목록 - 클릭하면 수정 가능합니다.

-
- -
- - - - - - - - - - - - -
ID삭제한글단어영어단어약어확정
-
- -
- -
- -
- -
- -
- + + + +
+ +
+
+
+
+

단어사전

+
+
+ +
+
+
+ + +
+
+
+
+ +
+
+

목록 - 클릭하면 수정 가능합니다.

+
+ +
+ + + + + + + + + + + + + +
ID삭제한글단어영어단어약어확정최근수정자수정시간
+
+ +
+ +
+ +
+ +
+ +
+ - - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - + +
+
- - - + + + + + + + + + + + + + + + + + + + // If any error was detected, prevent submission and display the error message + if (error) { + this.error(errorMsg); + return false; // prevent submission + } + } + }); + - - diff --git a/src/main/resources/templates/user/list.html b/src/main/resources/templates/user/list.html index b7451c9..7603943 100644 --- a/src/main/resources/templates/user/list.html +++ b/src/main/resources/templates/user/list.html @@ -35,7 +35,7 @@
-

출퇴근 관리

+

사용자 관리