만약 프로젝트가 실행되고있는 중간에 접근권한을 변경하려면 어떻게 해야할까?
많은 방식을 찾아봤지만 딱히 원하는 방법은 없었다.. spring 버전 2.7미만이었을 때는 이 블로그에서와 같이 Checker를 만들어서 적용하는 방법이 가능했는데, 이 방법은 사용자들이 api에 접근을 할 때마다 DB에서 관련 정보를 불러와 체크해야하는 단점이 있었고, 2.7 이상에서는 해당 방법이 적용되지 않는것 같았다. (내가 멍청해서 안된걸지도..^^)
어찌어찌 머리를 굴려서 생각해보니, 아예 필터쪽에서 관련 데이터들을 바꿔주면 되는거 아닌가? 라는 생각이 들었고, 몇번의 삽질끝에 해당 기능을 만들 수 있었다.
본 포스팅의 코드는 여기서 확인 가능합니다😉
기본적인 Security 설정은 이 포스팅을 기초로 하였고, SecurityService
클래스의 resetAuthorities()
를 통해 아래와 같이 접근권한을 바꾸는 로직을 만들었다.
GET | POST | |
---|---|---|
/admin | ROLE_ADMIN | ROLE_ADMIN |
/company | ROLE_ADMIN, ROLE_COMPANY | ROLE_ADMIN, ROLE_COMPANY |
/user | ROLE_ADMIN, ROLE_COMPANY, ROLE_USER | ROLE_ADMIN, ROLE_COMPANY, ROLE_USER |
코드
SecurityService.java
@Component
@RequiredArgsConstructor
public class SecurityService {
private final FilterSecurityInterceptor filterSecurityInterceptor;
private final UrlFilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource;
public void resetAuthorities() {
//SecurityConfig에 bean으로 등록된 UrlFilterInvocationSecurityMetadataSource에
//requestMap을 새로 만든 권한으로 reset시킨다.
urlFilterInvocationSecurityMetadataSource.reset(newRequestMap());
//기존의 FilterSecurityInterceptor에 SecurityMetadataSource를 교체해준다.
filterSecurityInterceptor.setSecurityMetadataSource(urlFilterInvocationSecurityMetadataSource);
}
//바꾸려는 접근권한 map..
private Map<RequestMatcher, List<ConfigAttribute>> newRequestMap() {
Map<RequestMatcher, List<ConfigAttribute>> requestMap = new HashMap<>();
requestMap.put(new AntPathRequestMatcher("/admin"),
Collections.singletonList(new SecurityConfig("ROLE_ADMIN")));
requestMap.put(new AntPathRequestMatcher("/company"),
Arrays.asList(new SecurityConfig("ROLE_ADMIN"), new SecurityConfig("ROLE_COMPANY")));
requestMap.put(new AntPathRequestMatcher("/user"),
Arrays.asList(new SecurityConfig("ROLE_ADMIN"), new SecurityConfig("ROLE_COMPANY"),
new SecurityConfig("ROLE_USER")));
return requestMap;
}
}
UrlFilterInvocationSecurityMetadataSource.java
@Slf4j
@Getter
public class UrlFilterInvocationSecurityMetadataSource implements
FilterInvocationSecurityMetadataSource {
private Map<RequestMatcher, List<ConfigAttribute>> requestMap;
//other codes..
public void reset(Map<RequestMatcher, List<ConfigAttribute>> requestMap) {
this.requestMap = requestMap;
}
}
이렇게 설정을 완료해 준 후, 컨트롤러에서 권한 수정 api를 만들어 resetAuthorities()
를 호출해주었다.
테스트코드는 기존의 것을 사용하였는데, 프로젝트 실행 후 권한이 수정되어 403에러를 발생시켜야 할 api들이 200을 발생시켜 테스트가 실패한 것을 확인 할 수 있다.
덧,
이 포스팅을 정리하면서 이런글을 발견했다..! 참고한건 아닌데 코드가 조금 유사한거같아서.. 내가 이상한 방법으로 하지 않았구나 마음이 놓인다..
이번 포스팅이 시큐리티 관련 마지막 포스팅이 될 것같다. 정말 시큐리티는 맨날 봐도 모르겟다.^^
언젠간 이해하겠지뭐..
'개발 일기 > spring' 카테고리의 다른 글
Spring Security 설정 (Dynamic) (2) | 2022.09.02 |
---|---|
Spring Security 설정 (Hierarchy) (0) | 2022.09.02 |
Spring Security 설정 (JWT 2) (0) | 2022.08.31 |
Spring Security 설정 (JWT 1) (2) | 2022.08.31 |
Spring Security 설정 (기본) (2) | 2022.08.31 |
댓글