티스토리 뷰
Spring Security 대신에 HandlerInterceptorAdapter를 사용하여 페이지를 권한에 따라 접근가능하도록 개발하기
돔돔이 2024. 9. 12. 10:39
Spring Security로 페이지를 권한에 따라 접근가능하도록 개발하는 방법에 대해서는
아래 포스팅에 작성해놓았으니 참고하세요!
[springboot] spring security로 DB 사용자권한별 페이지접속제한하기
[springboot] 토큰을 이용한 사용자인증 및 로그아웃 구현하기 (spring security 이용)
이번 포스팅에서는 Spring Security 대신에 HandlerInterceptorAdapter를 사용하여 권한에 따라 페이지에 접근이 가능하도록
개발한 내용에 대해서 적어보겠습니다.
일단 HandlerInterceptorAdapter를 사용하기에 앞서,
어떤 권한이 어떤 페이지URL에 접근이 가능하도록 하게 할 것인지 프로퍼티 설정파일을 먼저 작성합니다.
/src/main/resources 경로 아래에 access.properties 파일을 하나 생성하여 작성하였습니다.
/service/.*=0,1,2
/board/edit=0,1
/board/remove=0,1
...
위와 같이 /service/.*로 작성하면 service 하위에 포함된 모든 경로는 0,1,2 권한을 가진 모든 사용자가 접근이 가능하고,
/board/edit=0,1로 작성하면 /board/edit 경로에는 0,1만 접근이 가능하고, 2권한은 페이지 접근이 불가합니다.
이 프로퍼티 파일을 읽어 인터셉터에서 페이지별 접근권한을 설정합니다.
PermissionInterceptor라는 클래스파일을 하나 만들고, 페이지에 접근할 때마다 preHandle에서 경로별 허용된 권한을 확인합니다.
package kt.com.eduMng.AdminInterceptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;
public class PermissionInterceptor extends HandlerInterceptorAdapter {
protected Log log = LogFactory.getLog(PermissionInterceptor.class);
private LinkedHashMap<String, List<String>> roleAccessMap = new LinkedHashMap<>();
public PermissionInterceptor() {
loadRoleAccessConfigurations();
}
private void loadRoleAccessConfigurations() {
try {
Properties properties = new Properties();
properties.load(new ClassPathResource("access.properties").getInputStream());
// 설정 파일에서 경로 패턴과 권한을 읽어와서 Map에 저장
for (String key : properties.stringPropertyNames()) {
String[] roles = properties.getProperty(key).split(",");
roleAccessMap.put(key, Arrays.asList(roles));
}
} catch (IOException e) {
log.error("Failed to load role access configurations: " + e.getMessage());
}
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
try {
String requestURI = request.getRequestURI();
HttpSession session = request.getSession(false);
if(session != null) {
String auth = String.valueOf(session.getAttribute("auth"));
// 경로별 허용된 권한 확인 (정의된 순서대로 처리)
for (Map.Entry<String, List<String>> entry : roleAccessMap.entrySet()) {
String pattern = entry.getKey().replace("**", ".*");
if (requestURI.matches(pattern)) {
List<String> allowedRoles = entry.getValue();
if (entry.getValue().contains(sysSe)) {
return true;
} else {
response.sendRedirect(request.getContextPath() + "/");
return false;
}
}
}
// 설정에 없는 경로는 기본적으로 접근 허용
return true;
}
response.sendRedirect(request.getContextPath() + "/");
return false;
} catch (Exception e) {
throw e;
}
}
}
이제 이 PermissionInterceptor 클래스파일을 서블릿컨텍스트에서 읽을 수 있도록 servlet-context.xml에 작성해주면 끝!
<interceptors>
<interceptor>
<!-- 모든 요청을 PermissionInterceptor에서 처리 -->
<mapping path="/**"/>
<beans:bean class="{경로입력}.PermissionInterceptor"/>
</interceptor>
</interceptors>
...
</beans:beans>
여기서는 HandlerInterceptorAdapter를 사용했지만,
spring 5.3 이상에서는 HandlerInterceptorAdapter 를 사용하는 대신 HandlerInterceptor를 implements 해서 사용하는 방식으로 바뀌었다고 하니 참고하세요!