메뉴 권한 수정

This commit is contained in:
2025-12-30 11:28:52 +09:00
parent 98f5a6fa84
commit 412f4a0d5e
4 changed files with 62 additions and 5 deletions

View File

@@ -45,19 +45,50 @@ public class MenuAuthorizationManager implements AuthorizationManager<RequestAut
return new AuthorizationDecision(false); return new AuthorizationDecision(false);
} }
// DB에서 role에 허용된 메뉴 조회 boolean isAdmin = "ADMIN".equalsIgnoreCase(role);
List<MenuEntity> allowedMenus = menuAuthQueryRepository.findAllowedMenuUrlsByRole(role);
// URL별 권한 조회
List<MenuEntity> matchedMenus = menuAuthQueryRepository.findMenusByRequestPath(requestPath);
boolean isProtectedUrl = matchedMenus != null && !matchedMenus.isEmpty();
// URL별 권한에 라벨러, 검수자 권한이 있으면 , ADMIN도 false
if (isProtectedUrl) {
List<MenuEntity> allowedMenus = menuAuthQueryRepository.findAllowedMenuUrlsByRole(role);
if (allowedMenus == null || allowedMenus.isEmpty()) {
return new AuthorizationDecision(false);
}
for (MenuEntity menu : allowedMenus) {
String baseUri = menu.getMenuUrl();
if (baseUri == null || baseUri.isBlank()) {
continue;
}
if (matchUri(baseUri, requestPath)) {
return new AuthorizationDecision(true);
}
}
return new AuthorizationDecision(false);
}
// ✅ 3) 보호 URL이 아니면 ADMIN은 전부 허용
if (isAdmin) {
return new AuthorizationDecision(true);
}
// ✅ 4) 일반 role은 기존대로 매핑 기반
List<MenuEntity> allowedMenus = menuAuthQueryRepository.findAllowedMenuUrlsByRole(role);
if (allowedMenus == null || allowedMenus.isEmpty()) { if (allowedMenus == null || allowedMenus.isEmpty()) {
return new AuthorizationDecision(false); return new AuthorizationDecision(false);
} }
// menu_url(prefix) 기반 접근 허용 판단
for (MenuEntity menu : allowedMenus) { for (MenuEntity menu : allowedMenus) {
String baseUri = menu.getMenuUrl(); String baseUri = menu.getMenuUrl();
if (baseUri == null || baseUri.isBlank()) { if (baseUri == null || baseUri.isBlank()) {
continue; continue;
} }
if (matchUri(baseUri, requestPath)) { if (matchUri(baseUri, requestPath)) {
return new AuthorizationDecision(true); return new AuthorizationDecision(true);
} }

View File

@@ -83,9 +83,10 @@ public class SecurityConfig {
.requestMatchers("/api/user/**") .requestMatchers("/api/user/**")
.authenticated() .authenticated()
.anyRequest() .anyRequest()
// .access(redisAuthorizationManager) .access(menuAuthorizationManager)
.authenticated()) // .authenticated()
)
.addFilterBefore( .addFilterBefore(
jwtAuthenticationFilter, jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter UsernamePasswordAuthenticationFilter

View File

@@ -22,4 +22,12 @@ public interface MenuRepositoryCustom {
* @return * @return
*/ */
List<MenuEntity> findAllowedMenuUrlsByRole(String role); List<MenuEntity> findAllowedMenuUrlsByRole(String role);
/**
* url별 역할
*
* @param requestPath
* @return
*/
List<MenuEntity> findMenusByRequestPath(String requestPath);
} }

View File

@@ -79,4 +79,21 @@ public class MenuRepositoryImpl implements MenuRepositoryCustom {
.orderBy(menuEntity.menuOrder.asc().nullsLast()) .orderBy(menuEntity.menuOrder.asc().nullsLast())
.fetch(); .fetch();
} }
@Override
public List<MenuEntity> findMenusByRequestPath(String requestPath) {
return queryFactory
.selectDistinct(menuEntity)
.from(menuMappEntity)
.join(menuMappEntity.menuUid, menuEntity)
.where(
menuMappEntity.deleted.isFalse(),
menuEntity.deleted.isFalse(),
menuEntity.isUse.isTrue(),
menuEntity.menuUrl.isNotNull(),
menuEntity.menuUrl.isNotEmpty(),
menuEntity.menuUrl.eq(requestPath))
.orderBy(menuEntity.menuOrder.asc().nullsLast())
.fetch();
}
} }