diff --git a/pom.xml b/pom.xml index 3e9e7fe..ee62cd9 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 - 1.8 + 17 ${java.version} ${java.version} @@ -126,8 +126,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 + ${java.version} + ${java.version} UTF-8 diff --git a/src/main/java/cokr/xit/base/security/SecuredUserInfo.java b/src/main/java/cokr/xit/base/security/SecuredUserInfo.java index 403887e..1a065c3 100644 --- a/src/main/java/cokr/xit/base/security/SecuredUserInfo.java +++ b/src/main/java/cokr/xit/base/security/SecuredUserInfo.java @@ -1,6 +1,5 @@ package cokr.xit.base.security; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -146,7 +145,7 @@ public class SecuredUserInfo extends UserInfo implements UserDetails { @Override public boolean isAccountNonLocked() { - return isEnabled(); + return "N".equalsIgnoreCase(getUser().getLocked()); } @Override @@ -160,7 +159,7 @@ public class SecuredUserInfo extends UserInfo implements UserDetails { } private SecuredUserInfo seal() { - authorities = Provider.get().getAccessContext().getAuthorities(Arrays.asList(Authority.ANONYMOUS)); + authorities = Provider.get().getAccessContext().getAuthorities(List.of(Authority.ANONYMOUS)); sealed = true; return this; } diff --git a/src/main/java/cokr/xit/base/security/access/ApplicationAccess.java b/src/main/java/cokr/xit/base/security/access/ApplicationAccess.java index 498e4cf..111173c 100644 --- a/src/main/java/cokr/xit/base/security/access/ApplicationAccess.java +++ b/src/main/java/cokr/xit/base/security/access/ApplicationAccess.java @@ -1,12 +1,17 @@ package cokr.xit.base.security.access; import java.util.Collection; +import java.util.function.Supplier; import javax.annotation.Resource; import org.springframework.security.access.AccessDecisionVoter; import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.core.Authentication; +import org.springframework.security.web.access.intercept.RequestAuthorizationContext; +import org.springframework.stereotype.Component; import cokr.xit.base.security.AccessContext; import cokr.xit.base.security.SecuredUserInfo; @@ -17,22 +22,14 @@ import cokr.xit.foundation.Access; * 사용자가 애플리케이션의 기능을 실행할 수 있는지 판단한다. * @author mjkhan */ -public class ApplicationAccess extends AbstractComponent implements AccessDecisionVoter { - private boolean controlAccess; +@Component("applicationAccess") +public class ApplicationAccess + extends AbstractComponent + implements AccessDecisionVoter, AuthorizationManager { /** 권한별 가용 기능(URL) */ @Resource(name="accessContext") protected AccessContext accessContext; - /**접근 제어를 사용할지 설정한다. - * @param controlAccess 접근 제어 사용 여부 - *
  • 접근 제어를 사용하면 true
  • - *
  • 그렇지 않으면 false
  • - *
- */ - public void setControlAccess(boolean controlAccess) { - this.controlAccess = controlAccess; - } - @Override public boolean supports(ConfigAttribute attribute) { return true; @@ -45,9 +42,10 @@ public class ApplicationAccess extends AbstractComponent implements AccessDecisi @Override public int vote(Authentication authentication, Object obj, Collection attributes) { - if (!controlAccess) return ACCESS_GRANTED; + return vote(Access.current().getAction()); + } - String action = Access.current().getAction(); + public int vote(String action) { if (isEmpty(action)) return ACCESS_GRANTED; @@ -61,4 +59,17 @@ public class ApplicationAccess extends AbstractComponent implements AccessDecisi */ return ACCESS_DENIED; } + + private static final AuthorizationDecision + granted = new AuthorizationDecision(true), + denied = new AuthorizationDecision(false); + + @Override + public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext hreqCtx) { + switch (vote(authentication.get(), null, null)) { + case ACCESS_GRANTED: return granted; + case ACCESS_DENIED: return denied; + default: return null; + } + } } \ No newline at end of file diff --git a/src/main/java/cokr/xit/base/security/access/dao/AuthorityMapper.java b/src/main/java/cokr/xit/base/security/access/dao/AuthorityMapper.java index 96ad92b..047d343 100644 --- a/src/main/java/cokr/xit/base/security/access/dao/AuthorityMapper.java +++ b/src/main/java/cokr/xit/base/security/access/dao/AuthorityMapper.java @@ -1,6 +1,5 @@ package cokr.xit.base.security.access.dao; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -186,7 +185,7 @@ public interface AuthorityMapper extends AbstractMapper { * @return 권한 목록 */ default List getUserAuths(String userID) { - List list = getUserAuths(params().set("userIDs", Arrays.asList(userID))); + List list = getUserAuths(params().set("userIDs", List.of(userID))); return list.stream() .map(row -> row.string("AUTH_ID")) .collect(Collectors.toList()); diff --git a/src/main/java/cokr/xit/base/security/authentication/service/bean/AuthenticationBean.java b/src/main/java/cokr/xit/base/security/authentication/service/bean/AuthenticationBean.java index 8acd7a1..b47cdbf 100644 --- a/src/main/java/cokr/xit/base/security/authentication/service/bean/AuthenticationBean.java +++ b/src/main/java/cokr/xit/base/security/authentication/service/bean/AuthenticationBean.java @@ -11,7 +11,6 @@ import org.springframework.stereotype.Component; import cokr.xit.base.security.authentication.AuthenticationPolicy; import cokr.xit.base.security.authentication.dao.PolicyMapper; import cokr.xit.base.user.dao.UserMapper; -import cokr.xit.base.user.service.UserQuery; import cokr.xit.foundation.AbstractComponent; import cokr.xit.foundation.User; import cokr.xit.foundation.component.QueryRequest; @@ -32,12 +31,7 @@ public class AuthenticationBean extends AbstractComponent { * @return 사용자 */ public User getUser(Map params) { - UserQuery req = new UserQuery() - .setUserIDs((String)params.get("userID")); - req.setPassword(true); - List users = userMapper.getUsers(req); - - return !users.isEmpty() ? users.get(0) : null; + return userMapper.getUser(params); } /**주어진 아이디의 사용자를 가져온다. diff --git a/src/main/java/cokr/xit/base/security/authentication/service/bean/AuthenticationServiceBean.java b/src/main/java/cokr/xit/base/security/authentication/service/bean/AuthenticationServiceBean.java index 6713156..4eb862a 100644 --- a/src/main/java/cokr/xit/base/security/authentication/service/bean/AuthenticationServiceBean.java +++ b/src/main/java/cokr/xit/base/security/authentication/service/bean/AuthenticationServiceBean.java @@ -86,10 +86,8 @@ public class AuthenticationServiceBean extends DaoAuthenticationProvider impleme AuthenticationExtraDetails extraDetails = (AuthenticationExtraDetails)obj; Map params = extraDetails.getParams(); - log().debug("Authentication details: {}", params); SecuredUserInfo userInfo = loadUser(params); - boolean valid = validate(userInfo, params); if (valid) checkAgainstPolicy(extraDetails, userInfo); diff --git a/src/main/java/cokr/xit/base/security/authentication/web/AuthenticationSuccess.java b/src/main/java/cokr/xit/base/security/authentication/web/AuthenticationSuccess.java index de546d0..617b078 100644 --- a/src/main/java/cokr/xit/base/security/authentication/web/AuthenticationSuccess.java +++ b/src/main/java/cokr/xit/base/security/authentication/web/AuthenticationSuccess.java @@ -30,16 +30,16 @@ public class AuthenticationSuccess extends SavedRequestAwareAuthenticationSucces @Resource(name="objectMapper") private ObjectMapper objectMapper; - private boolean rememberUsername; + private boolean rememberCredentials; - /**로그인 유지 여부를 설정한다. - * @param remember 로그인 유지 여부 - *
  • 로그인을 유지하려면 true
  • + /**로그인 정보 유지 여부를 설정한다. + * @param remember 로그인 정보 유지 여부 + *
    • 로그인 정보를 유지하려면 true
    • *
    • 그렇지 않으면 false
    • *
    */ - public void setRememberUsername(boolean remember) { - this.rememberUsername = remember; + public void setRememberCredentials(boolean remember) { + this.rememberCredentials = remember; } /**사용자 인증 서비스 인터페이스를 반환한다. @@ -84,8 +84,12 @@ public class AuthenticationSuccess extends SavedRequestAwareAuthenticationSucces } private void remember(UserInfo user, HttpServletRequest hreq, HttpServletResponse hresp) { - boolean remember = rememberUsername && "true".equals(hreq.getParameter("remember")); - Cookie cookie = new Cookie("username", remember ? user.getUsername() : ""); + boolean remember = rememberCredentials && "true".equals(hreq.getParameter("remember")); + addCookie(hresp, remember, "userAccount", user.getAccount()); + } + + private void addCookie(HttpServletResponse hresp, boolean remember, String name, String value) { + Cookie cookie = new Cookie(name, remember ? value : ""); cookie.setMaxAge(remember ? Integer.MAX_VALUE : 0); hresp.addCookie(cookie); } diff --git a/src/main/java/cokr/xit/base/security/authentication/web/LogoutSuccess.java b/src/main/java/cokr/xit/base/security/authentication/web/LogoutSuccess.java index ff9475a..9705b96 100644 --- a/src/main/java/cokr/xit/base/security/authentication/web/LogoutSuccess.java +++ b/src/main/java/cokr/xit/base/security/authentication/web/LogoutSuccess.java @@ -4,7 +4,6 @@ import java.io.IOException; import javax.annotation.Resource; import javax.servlet.ServletException; -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -24,6 +23,7 @@ import org.springframework.web.context.WebApplicationContext; import cokr.xit.base.security.authentication.service.AuthenticationService; import cokr.xit.foundation.Assert; import cokr.xit.foundation.Log; +import cokr.xit.foundation.web.Kookie; /**로그아웃 성공 핸들러 * @author mjkhan @@ -76,39 +76,43 @@ public class LogoutSuccess extends SimpleUrlLogoutSuccessHandler implements Appl HttpSession session = hreq.getSession(false); if (session != null) session.invalidate(); - removeCookies(hreq, hresp); + + new Kookie() + .set(hreq) + .set(hresp) + .remove(); + hreq.logout(); hresp.setStatus(HttpServletResponse.SC_OK); hresp.sendRedirect(getSuccessUrl(hreq.getContextPath())); } - /**쿠키에 저장된 값들을 삭제한다. + /* 쿠키에 저장된 값들을 삭제한다. * @param hreq 서블릿 요청 * @param hresp 서블릿 응답 - */ protected void removeCookies(HttpServletRequest hreq, HttpServletResponse hresp) { Cookie[] cookies = hreq.getCookies(); if (cookies == null || cookies.length < 1) return; for (Cookie cookie: cookies) { - removeCookie(cookie, "JSESSIONID", "username"); - hresp.addCookie(cookie); + removeCookie(hresp, cookie, "JSESSIONID", "userAccount"); } - } + }*/ - /**지정하는 이름의 쿠키값을 삭제한다. + /* 지정하는 이름의 쿠키값을 삭제한다. + * @param hresp 서블릿 응답 * @param cookie 쿠키 * @param cookieNames 쿠키값의 이름 - */ - protected void removeCookie(Cookie cookie, String... cookieNames) { + protected void removeCookie(HttpServletResponse hresp, Cookie cookie, String... cookieNames) { for (String name: cookieNames) { if (!name.equals(cookie.getName())) continue; cookie.setMaxAge(0); cookie.setValue(""); + hresp.addCookie(cookie); } - } + }*/ @Override public void setApplicationContext(ApplicationContext actx) throws BeansException { diff --git a/src/main/java/cokr/xit/base/security/crypto/KeyFactory.java b/src/main/java/cokr/xit/base/security/crypto/KeyFactory.java index 587e3ec..dbd1858 100644 --- a/src/main/java/cokr/xit/base/security/crypto/KeyFactory.java +++ b/src/main/java/cokr/xit/base/security/crypto/KeyFactory.java @@ -3,7 +3,7 @@ package cokr.xit.base.security.crypto; import java.security.Key; import java.security.SecureRandom; import java.security.spec.KeySpec; -import java.util.Arrays; +import java.util.List; import javax.crypto.KeyGenerator; import javax.crypto.SecretKeyFactory; @@ -30,7 +30,7 @@ public class KeyFactory extends AbstractComponent { * @return KeyFactory */ public KeyFactory setKeySize(int keySize) { - if (!Arrays.asList(128, 192, 256).contains(keySize)) + if (!List.of(128, 192, 256).contains(keySize)) throw new IllegalArgumentException("keySize must be either of 128, 192, 256"); this.keySize = keySize;