Initial commit

This commit is contained in:
2026-05-29 17:49:25 +09:00
commit 330105cb27
1081 changed files with 148694 additions and 0 deletions
@@ -0,0 +1,129 @@
= 권한 관리
== 권한 체크 로직
권한 체크는 AuthorizationInterceptor에서 사용자가 가지고 있는 메뉴의 권한 목록을 기반으로 URL Base 로 체크가 되고 있다.
[source,java]
----
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
-- 생략 --
String httpMethod = request.getMethod();
String decodedUrl = WebUtil.getDecodedRequestUrl(request, request.getRequestURI().substring(request.getContextPath().length()));
String queryString = "";
if (decodedUrl.indexOf('?') > -1) {
String[] uri = decodedUrl.split("\\?");
decodedUrl = uri[0];
queryString = uri[1];
}
for (Api api : authMenuList) {
if (api.getHttpMethod().equals(httpMethod) && checkUriMatch(api.getApiPath(), api.getApiParameters(), decodedUrl, queryString)) {
return true;
}
}
throw new AuthorizationException("API 권한 없음");
}
----
[source,java]
----
public boolean checkUriMatch(String apiPath, String apiParameters, String decodedUrl, String queryString){
Map<String, String> requiredParamMap = new HashMap<>();
if( StringUtils.isNotEmpty(apiParameters)){
requiredParamMap = Splitter.on('&').trimResults().withKeyValueSeparator('=').split(apiParameters);
}
UriTemplate uriTemplate = new UriTemplate(apiPath);
if ( uriTemplate.matches(decodedUrl) ){
if( requiredParamMap.size() == 0 ) return true;
for (Map.Entry<String, String> entry : requiredParamMap.entrySet()) {
log.debug("Required Param : " + entry.getKey() + " Value : " + entry.getValue());
Map<String, String> requestParamMap = getRequestParam(queryString);
if( !requestParamMap.containsKey(entry.getKey()) || !(entry.getValue()).equals(requestParamMap.get(entry.getKey()))){
return false;
}
}
return true;
}else{
return false;
}
}
----
== 권한별 메뉴 가져오기
SPA(Single Page Application) 방식으로 최초 메인화면 진입시에 사용자의 권한에 맞는 메뉴 목록을 조회하여 보여준다. +
[source,java]
----
@RestController
@RequestMapping("/auth")
public class MenuController {
--생략--
@Operation(summary = "사용자의 권한이 있는 메뉴 조회")
@GetMapping("/menus-user-auth")
public List<Menu> getMenuListByAuth() {
return menuService.getMenuListByAuth(Account.currentUser().getUserId());
}
--생략--
}
----
일반 사용자와 시스템 어드민 사용자의 권한 메뉴 조회 서비스가 분리 되어 있다.
[source,java]
----
@Service
public class MenuServiceImpl implements MenuService {
--생략--
@Override
public List<Menu> getMenuListByAuth(String userId) {
if (Account.currentUser().isSystemAdminUser()) return this.getMenuListByAdminAuth();
else return this.getMenuListByUserAuth(userId);
}
--생략--
}
----
접속중인 상태에서 권한이 변경될 경우 화면 재진입(다시 로그인 또는 브라우저 새로고침)을 통해서 변경된 권한의 메뉴 목록을 다시 로드할 수 있다.
== 권한에 따른 UI Control
SDL에서는 역할관리에서 정의해놓은 역할별로 4개의 권한을 지정할 수 있다. +
최초 화면 진입시 조회한 사용자가 접근 가능한 메뉴 목록에 해당 메뉴에 대한 권한 목록을 함께 가지고 있으며 화면에서 버튼에 directive로 지정함으로써 show/hide 처리를 자동으로 처리한다.
역할관리를 통한 메뉴별 권한 등록
image::front_01_03.png[]
vue 내에서 authorization directive를 통해 버튼 별 권한을 정의한다.(배열로 정의할 경우 여러개 중에 하나만 매칭되도 show처리 됨)
* 여러개의 권한을 둘 경우
[source, html]
----
<button
type="button"
class="btn btn-primary btn-sm"
v-authorization="['UPDATE', 'EXECUTE']"
@click="onApprWrite"
>
{{ $t('sdl.approval.label.APPROVE') }}
</button>
----
* 하나의 권한을 둘 경우
[source, html]
----
<button type="button"
class="btn btn-primary btn-sm"
v-authorization="'UPDATE'"
@click="onApprWrite"
>
{{ $t('sdl.approval.label.APPROVE') }}
</button>
----
* 관리자일 경우는 directive 지정 상관 없이 무조건 show 처리된다.