diff --git a/src/main/java/com/eactive/httpmockserver/common/exception/CustomGlobalExceptionHandler.java b/src/main/java/com/eactive/httpmockserver/common/exception/CustomGlobalExceptionHandler.java index eb663ea..26cd714 100644 --- a/src/main/java/com/eactive/httpmockserver/common/exception/CustomGlobalExceptionHandler.java +++ b/src/main/java/com/eactive/httpmockserver/common/exception/CustomGlobalExceptionHandler.java @@ -1,5 +1,6 @@ package com.eactive.httpmockserver.common.exception; +import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -10,6 +11,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep import java.time.LocalDateTime; +@Order(1) @RestControllerAdvice(annotations = RestController.class) public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler { diff --git a/src/main/java/com/eactive/httpmockserver/common/exception/PortalGlobalExceptionHandler.java b/src/main/java/com/eactive/httpmockserver/common/exception/PortalGlobalExceptionHandler.java index 8edbe70..68e1c2e 100644 --- a/src/main/java/com/eactive/httpmockserver/common/exception/PortalGlobalExceptionHandler.java +++ b/src/main/java/com/eactive/httpmockserver/common/exception/PortalGlobalExceptionHandler.java @@ -3,6 +3,7 @@ package com.eactive.httpmockserver.common.exception; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -11,6 +12,7 @@ import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; @ControllerAdvice(annotations = Controller.class) +@Order(2) public class PortalGlobalExceptionHandler { private final Logger log = LoggerFactory.getLogger(getClass()); diff --git a/src/main/java/com/eactive/httpmockserver/config/PortalAuthenticationFailureHandler.java b/src/main/java/com/eactive/httpmockserver/config/PortalAuthenticationFailureHandler.java index 8068629..ab82926 100644 --- a/src/main/java/com/eactive/httpmockserver/config/PortalAuthenticationFailureHandler.java +++ b/src/main/java/com/eactive/httpmockserver/config/PortalAuthenticationFailureHandler.java @@ -1,6 +1,7 @@ package com.eactive.httpmockserver.config; import com.eactive.httpmockserver.common.entity.EnabledStatus; +import com.eactive.httpmockserver.common.exception.UserNotFoundException; import com.eactive.httpmockserver.login.controller.LoginController; import com.eactive.httpmockserver.user.entity.StaffUser; import com.eactive.httpmockserver.user.entity.User; @@ -29,23 +30,25 @@ public class PortalAuthenticationFailureHandler implements AuthenticationFailure @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) + @Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {AuthenticationException.class, UserNotFoundException.class}) public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { String username = request.getParameter("id"); + try { + User user = userService.findByUserId(username); + if (user != null) { + user.setLockCnt(user.getLockCnt() + 1); + if (user.getLockCnt() >= 5) { + user.setLockAt(EnabledStatus.Y); + } - User user = userService.findByUserId(username); - user.setLockCnt(user.getLockCnt() + 1); - if (user.getLockCnt() >= 5) { - user.setLockAt(EnabledStatus.Y); + staffUserRepository.save((StaffUser) user); + } + } catch (UserNotFoundException ignored) { } - staffUserRepository.save((StaffUser) user); - - request.getSession().setAttribute(LoginController.LOGIN_MESSAGE, exception.getMessage()); - + request.getSession().setAttribute(LoginController.LOGIN_MESSAGE, exception.getLocalizedMessage()); String contextPath = request.getContextPath(); - response.sendRedirect(contextPath + "/login"); } } diff --git a/src/main/java/com/eactive/httpmockserver/config/PortalAuthenticationManager.java b/src/main/java/com/eactive/httpmockserver/config/PortalAuthenticationManager.java index 2ba08ab..f185e19 100644 --- a/src/main/java/com/eactive/httpmockserver/config/PortalAuthenticationManager.java +++ b/src/main/java/com/eactive/httpmockserver/config/PortalAuthenticationManager.java @@ -30,9 +30,9 @@ public class PortalAuthenticationManager implements AuthenticationManager { UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication; String username = token.getName(); String password = token.getCredentials().toString(); + String encryptPassword = encryptionUtil.encryptPassword(password, username); UserDetails user = userService.loadUserByUsername(username); - String encryptPassword = encryptionUtil.encryptPassword(password, username); if (!user.isEnabled()) { throw new DisabledException("계정이 " + ((User) user).getStatus().getDescription() + "상태입니다. 관리자에게 문의하세요."); @@ -47,8 +47,6 @@ public class PortalAuthenticationManager implements AuthenticationManager { UsernamePasswordAuthenticationToken authorityToken = new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities()); authorityToken.setDetails(user); SecurityContextHolder.getContext().setAuthentication(authorityToken); - ((User) user).setLockCnt(0); - userService.updateUser((User) user); return authorityToken; } diff --git a/src/main/java/com/eactive/httpmockserver/config/PortalConfigAppDatasource.java b/src/main/java/com/eactive/httpmockserver/config/PortalConfigAppDatasource.java index d30cba7..ed3f71d 100644 --- a/src/main/java/com/eactive/httpmockserver/config/PortalConfigAppDatasource.java +++ b/src/main/java/com/eactive/httpmockserver/config/PortalConfigAppDatasource.java @@ -3,10 +3,13 @@ package com.eactive.httpmockserver.config; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import org.springframework.data.domain.AuditorAware; import org.springframework.data.envers.repository.support.EnversRevisionRepositoryFactoryBean; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; /** * @author diff --git a/src/main/java/com/eactive/httpmockserver/user/controller/AccountController.java b/src/main/java/com/eactive/httpmockserver/user/controller/AccountController.java index 2f31710..66e4c42 100644 --- a/src/main/java/com/eactive/httpmockserver/user/controller/AccountController.java +++ b/src/main/java/com/eactive/httpmockserver/user/controller/AccountController.java @@ -26,7 +26,7 @@ public class AccountController { @GetMapping("/change_password.do") public String changePassword(ModelMap model, @ModelAttribute("passwordChangeRequest") PasswordChangeRequestDTO passwordChangeRequestDTO) { - return "apps/main/updatePw"; + return "page/updatePw"; } @PostMapping(value = "/update_password.do") @@ -39,7 +39,7 @@ public class AccountController { if (result.hasErrors()) { model.addAttribute("errors", result); - return "apps/main/updatePw"; + return "page/updatePw"; } String oldPassword = passwordChangeRequestDTO.getOldPassword(); @@ -51,7 +51,7 @@ public class AccountController { model.addAttribute("resultMsg", resultMsg); model.addAttribute("passwordChangeRequest", new PasswordChangeRequestDTO()); - return "apps/main/updatePw"; + return "page/updatePw"; } diff --git a/src/main/java/com/eactive/httpmockserver/user/service/UserService.java b/src/main/java/com/eactive/httpmockserver/user/service/UserService.java index d11af15..5682bea 100644 --- a/src/main/java/com/eactive/httpmockserver/user/service/UserService.java +++ b/src/main/java/com/eactive/httpmockserver/user/service/UserService.java @@ -28,7 +28,11 @@ public class UserService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - return staffUserRepository.findByUserId(username).orElseThrow(() -> new UserNotFoundException(USER_NOT_FOUND_MESSAGE)); + try { + return findByUserId(username); + } catch (UserNotFoundException e) { + throw new UsernameNotFoundException(e.getMessage()); + } } public User findByUserId(String userId) { diff --git a/src/main/resources/lucy-xss-servlet-filter-rule.xml b/src/main/resources/lucy-xss-servlet-filter-rule.xml new file mode 100644 index 0000000..61a0078 --- /dev/null +++ b/src/main/resources/lucy-xss-servlet-filter-rule.xml @@ -0,0 +1,54 @@ + + + + + + + xssPreventerDefender + com.navercorp.lucy.security.xss.servletfilter.defender.XssPreventerDefender + + + + + xssSaxFilterDefender + com.navercorp.lucy.security.xss.servletfilter.defender.XssSaxFilterDefender + + lucy-xss-sax.xml + false + + + + + + xssFilterDefender + com.navercorp.lucy.security.xss.servletfilter.defender.XssFilterDefender + + lucy-xss.xml + true + + + + + + + xssFilterDefender + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/lucy-xss.xml b/src/main/resources/lucy-xss.xml new file mode 100644 index 0000000..aade0a3 --- /dev/null +++ b/src/main/resources/lucy-xss.xml @@ -0,0 +1,1909 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/message/message_en.properties b/src/main/resources/message/message_en.properties index a4a88ce..739fd54 100644 --- a/src/main/resources/message/message_en.properties +++ b/src/main/resources/message/message_en.properties @@ -41,4 +41,12 @@ lastLockDate=Lock Date lastPasswordChangeDate=Last Password Change Date common.nodata.msg=No Data name=Name -common.delete.msg=Confirm to Delete? \ No newline at end of file +common.delete.msg=Confirm to Delete? + +comUssUmt.userManagePasswordUpdt.oldPass=Current Password +comUssUmt.userManagePasswordUpdt.pass=Password +comUssUmt.userManagePasswordUpdt.passConfirm=Password Confirmation +button.cancel=cancel +success.common.update=Successfully chnaged. +fail.user.passwordUpdate2=New passwords not matched. +fail.user.passwordUpdate1=Current password is incorrect. \ No newline at end of file diff --git a/src/main/resources/message/message_ko.properties b/src/main/resources/message/message_ko.properties index f9623f6..1dd52c8 100644 --- a/src/main/resources/message/message_ko.properties +++ b/src/main/resources/message/message_ko.properties @@ -47,4 +47,12 @@ lastLockDate=\uC7A0\uAE40 \uC77C\uC2DC lastPasswordChangeDate=\uBE44\uBC00\uBC88\uD638 \uBCC0\uACBD \uC77C\uC2DC common.nodata.msg=\uB370\uC774\uD130\uAC00 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. name=\uC774\uB984 -common.delete.msg=\uC0AD\uC81C \uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C? \ No newline at end of file +common.delete.msg=\uC0AD\uC81C \uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C? + +comUssUmt.userManagePasswordUpdt.pass=\uBE44\uBC00\uBC88\uD638 +comUssUmt.userManagePasswordUpdt.passConfirm=\uBE44\uBC00\uBC88\uD638\uD655\uC778 +comUssUmt.userManagePasswordUpdt.oldPass=\uAE30\uC874 \uD328\uC2A4\uC6CC\uB4DC +button.cancel=\uCDE8\uC18C +success.common.update=\uC815\uC0C1\uC801\uC73C\uB85C \uBCC0\uACBD\uB418\uC5C8\uC2B5\uB2C8\uB2E4. +fail.user.passwordUpdate2=\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. +fail.user.passwordUpdate1=\uAE30\uC874 \uBE44\uBC00\uBC88\uD638\uAC00 \uD2C0\uB838\uC2B5\uB2C8\uB2E4. \ No newline at end of file diff --git a/src/main/resources/templates/fragment/header.html b/src/main/resources/templates/fragment/header.html index 795d862..7876970 100644 --- a/src/main/resources/templates/fragment/header.html +++ b/src/main/resources/templates/fragment/header.html @@ -35,7 +35,7 @@ 로그인 + 비밀번호 변경 diff --git a/src/main/resources/templates/page/tester/apiTester.html b/src/main/resources/templates/page/tester/apiTester.html index c0b18fe..660d910 100644 --- a/src/main/resources/templates/page/tester/apiTester.html +++ b/src/main/resources/templates/page/tester/apiTester.html @@ -558,8 +558,6 @@ select.empty(); sidemenu.empty(); - let filter = $('#filter_text').val(); - for (let i = 0; i < collections.length; i++) { let template = $('#collectionTemplate').children().clone(); @@ -809,8 +807,6 @@ }); }, saveAPIRequest: function(model){ - console.log(model); - this.currentAjaxRequest = $.ajax({ url: '/mgmt/collections/{collectionId}/apis/save.do'.replace('{collectionId}', model.collectionId), type: 'POST', diff --git a/src/main/resources/templates/page/updatePw.html b/src/main/resources/templates/page/updatePw.html new file mode 100644 index 0000000..03cd725 --- /dev/null +++ b/src/main/resources/templates/page/updatePw.html @@ -0,0 +1,83 @@ + + + + + + +
+
+
+
+

비밀 번호 변경

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