From 83da0967a6184fa593aa73069bdb04adbeb896b4 Mon Sep 17 00:00:00 2001 From: mjkhan21 Date: Fri, 16 Jun 2023 18:17:07 +0900 Subject: [PATCH] =?UTF-8?q?Authority,=20AccessContext,=20SecuredUserInfo?= =?UTF-8?q?=20->=20ActionGroup=EA=B4=80=EB=A0=A8=20=EB=A9=94=EC=86=8C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cokr/xit/base/security/AccessContext.java | 20 +++++- .../cokr/xit/base/security/Authority.java | 63 ++++++++++++++----- .../xit/base/security/SecuredUserInfo.java | 21 ++++++- .../security/access/ApplicationAccess.java | 4 +- 4 files changed, 88 insertions(+), 20 deletions(-) diff --git a/src/main/java/cokr/xit/base/security/AccessContext.java b/src/main/java/cokr/xit/base/security/AccessContext.java index 875357a..629a2e3 100644 --- a/src/main/java/cokr/xit/base/security/AccessContext.java +++ b/src/main/java/cokr/xit/base/security/AccessContext.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Component; import cokr.xit.base.security.access.dao.AuthorityMapper; import cokr.xit.foundation.AbstractComponent; +import cokr.xit.foundation.data.DataObject; /**애플리케이션이 정의하거나 등록한 권한과 각 권한이 실행할 수 있는 기능(URL)들을 로드하여 * 사용자의 권한 체크에 정보를 제공한다.
@@ -48,7 +49,24 @@ public class AccessContext extends AbstractComponent implements ApplicationConte .filter(authority -> Authority.Type.IMPLICIT.equals(authority.type())) .collect(Collectors.toList()); - authorityMapper.getActionList().stream() + List authorityActions = authorityMapper.getActionList(); + authorityActions.stream() // 권한별 기능그룹 설정 + .map(row -> Map.of("AUTH_ID", row.get("AUTH_ID"), "GRP_ID", row.get("GRP_ID"))) + .collect(Collectors.groupingBy( + row -> row.get("AUTH_ID"), + Collectors.toSet() + )) + .forEach((authID, byAuth) -> { + List groupIDs = byAuth.stream() + .map(row -> (String)row.get("GRP_ID")) + .collect(Collectors.toList()); + + Authority authority = authorityIndex.get(authID); + if (authority != null) + authority.setActionGroups(groupIDs); + }); + + authorityActions.stream() // 권한별 기능(URL) 설정 .collect(Collectors.groupingBy(row -> row.string("AUTH_ID"))) .forEach((authID, actions) -> { List actionList = actions.stream() diff --git a/src/main/java/cokr/xit/base/security/Authority.java b/src/main/java/cokr/xit/base/security/Authority.java index b306519..ff25a42 100644 --- a/src/main/java/cokr/xit/base/security/Authority.java +++ b/src/main/java/cokr/xit/base/security/Authority.java @@ -52,7 +52,9 @@ public class Authority extends AbstractEntity implements GrantedAuthority { description, infoScope, userInfoScope; - private List actions; + private List + actionGroups, + actions; /**{@link Type 권한 유형} 코드를 반환한다. * @return 권한 유형 코드 @@ -82,6 +84,7 @@ public class Authority extends AbstractEntity implements GrantedAuthority { /**권한 id를 설정한다. * @param id 권한 id + * @return 현재 Authority */ public Authority setId(String id) { this.id = id; @@ -97,6 +100,7 @@ public class Authority extends AbstractEntity implements GrantedAuthority { /**권한 이름을 설정한다. * @param name 권한 이름 + * @return 현재 Authority */ public Authority setName(String name) { this.name = name; @@ -132,6 +136,7 @@ public class Authority extends AbstractEntity implements GrantedAuthority { *
  • ALL - 모든 정보
  • *
  • SELF - 사용자가 등록한 정보
  • *
+ * @return 현재 Authority */ public Authority setInfoScope(String infoScope) { this.infoScope = infoScope; @@ -153,17 +158,58 @@ public class Authority extends AbstractEntity implements GrantedAuthority { *
  • ALL - 모든 사용자정보
  • *
  • SELF - 사용자 자신의 정보
  • *
+ * @return 현재 Authority */ public Authority setUserInfoScope(String userInfoScope) { this.userInfoScope = userInfoScope; return this; } + /**실행할 수 있는 기능그룹을 반환한다. + * @return 실행할 수 있는 기능그룹 + */ + public List getActionGroups() { + return Assert.ifEmpty(actionGroups, Collections::emptyList); + } + + /**지정한 기능그룹이 허용되는지 반환한다. + * @param actionGroups 기능그룹 + * @return 기능그룹의 허용 여부 + *
  • 기능그룹이 허용되 있으면 true
  • + *
  • 기능그룹이 허용되 있지 않으면 false
  • + *
+ */ + public boolean isActionGroupGranted(String actionGroup) { + return Type.SUPER.equals(type()) + || getActionGroups().contains(actionGroup); + } + + /**실행할 수 있는 기능그룹을 설정한다. + * @param actionGroups 기능그룹 + * @return 현재 Authority + */ + public Authority setActionGroups(List actionGroups) { + this.actionGroups = actionGroups; + return this; + } + + /**action을 실행할 권한이 있는지 반환한다. + * @param action 실행할 기능(URL) + * @return + *
  • 기능을 실행할 권한이 있으면 true
  • + *
  • 기능을 실행할 권한이 없으면 false
  • + *
+ */ + public boolean isActionGranted(String action) { + return Type.SUPER.equals(type()) + || getActions().contains(action); + } + /**실행기능(URL)을 반환한다. * @return 실행기능(URL) */ public List getActions() { - return actions != null ? actions : Collections.emptyList(); + return Assert.ifEmpty(actions, Collections::emptyList); } /**실행기능(URL)을 설정한다. @@ -205,19 +251,6 @@ public class Authority extends AbstractEntity implements GrantedAuthority { return Assert.ifEmpty(infoScopes != null ? infoScopes.get(infoType) : null, () -> "none"); } - /**action을 실행할 권한이 있는지 반환한다. - * @param action 실행할 기능(URL) - * @return - *
  • 기능을 실행할 권한이 있으면 true
  • - *
  • 기능을 실행할 권한이 없으면 false
  • - *
- */ - public boolean isGranted(String action) { - if (Type.SUPER.equals(type())) return true; - - return getActions().contains(action); - } - @Override public String toString() { return String.format("%s{id:'%s', name:'%s'}", getClass().getSimpleName(), getId(), getName()); diff --git a/src/main/java/cokr/xit/base/security/SecuredUserInfo.java b/src/main/java/cokr/xit/base/security/SecuredUserInfo.java index 1a065c3..0c67f63 100644 --- a/src/main/java/cokr/xit/base/security/SecuredUserInfo.java +++ b/src/main/java/cokr/xit/base/security/SecuredUserInfo.java @@ -79,10 +79,27 @@ public class SecuredUserInfo extends UserInfo implements UserDetails { *
  • 기능을 실행할 권한이 없으면 false
  • * */ - public boolean isGranted(String action) { + public boolean isActionGranted(String action) { if (authorities != null && !authorities.isEmpty()) { for (Authority authority: authorities) { - if (authority.isGranted(action)) + if (authority.isActionGranted(action)) + return true; + } + } + return false; + } + + /**사용자에게 기능그룹을 실행할 권한이 있는지 반환한다. + * @param actionGroup 실행그룹 + * @return + *
    • 기능그룹을 실행할 권한이 있으면 true
    • + *
    • 기능그룹을 실행할 권한이 없으면 false
    • + *
    + */ + public boolean isActionGroupGranted(String actionGroup) { + if (authorities != null && !authorities.isEmpty()) { + for (Authority authority: authorities) { + if (authority.isActionGroupGranted(actionGroup)) return true; } } 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 111173c..e676582 100644 --- a/src/main/java/cokr/xit/base/security/access/ApplicationAccess.java +++ b/src/main/java/cokr/xit/base/security/access/ApplicationAccess.java @@ -50,11 +50,11 @@ public class ApplicationAccess return ACCESS_GRANTED; SecuredUserInfo userInfo = currentUser(); - if (userInfo.isGranted(action)) + if (userInfo.isActionGranted(action)) return ACCESS_GRANTED; /* for (Authority authority: accessContext.getImplicits()) - if (authority.isGranted(action)) + if (authority.isActionGranted(action)) return ACCESS_GRANTED; */ return ACCESS_DENIED;