본문 바로가기
개발 일기/spring

Spring security (접근권한 변경)

by URMOO 2022. 9. 6.
반응형

만약 프로젝트가 실행되고있는 중간에 접근권한을 변경하려면 어떻게 해야할까?

 

많은 방식을 찾아봤지만 딱히 원하는 방법은 없었다.. 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

댓글