129 lines
4.4 KiB
Plaintext
129 lines
4.4 KiB
Plaintext
= 권한 관리
|
|
|
|
== 권한 체크 로직
|
|
|
|
권한 체크는 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 처리된다. |