Spring Security 권한을 DB를 통해 동적으로 관리하기

hyeokjin·2022년 6월 19일
0
post-thumbnail

이번에는 사용자별 권한을 DB에 저장하여 동적으로 관리해보자

예시: https://dkyou.tistory.com/33?category=877213

해당 예시 사이트를 참고했다.
예시와 다르게 JPA를 이용하지않고 유저정보를 직접 DB에서 조회하여 구현했다.

핵심내용과, 수정한 부분만을 살펴보자.

로그인 필터를 만들어준다 (customFilterSecurityInterceptor)
주석을 잘 살펴보자, MetaDataSource를 수정하면 어떤일이 발생하는지 잘 알아두는것이 좋겠다.

    @Bean
    public FilterSecurityInterceptor customFilterSecurityInterceptor() throws Exception {
        FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor();
        // 새로운 보안 메타데이터 소스를 설정하는데, urlFilterInvocationSecurityMetadataSource()라는 메서드로 하겠다는 뜻입니다.
        // 그런데 DB 와 연동해서 권한과 자원에 대한 제어를 하는 클래스는 사용자가 직접 구현한 UrlFilterInvocationSecurityMetadataSoruce 가 처리하도록 되어 있기 때문에
        // security config의 .anyRequest().authenticated() 구문을 해석할 수가 없고 또한 security config의 .anyRequest().authenticated() 구문에 대한 참조 자체를 하지도 않습니다.
        // 즉 인증 사용자 및 비인증 사용자 모두 DB 에서 관리하는 자원과 권한의 정책에 따라 접근여부를 결정해야 합니다.
        filterSecurityInterceptor.setSecurityMetadataSource(urlFilterInvocationSecurityMetadataSource());   // 권한정보 셋팅
        /**
         * affirmativeBased : 하나라도 승인이 있으면 승인 처리
         * ConsensusBased   : 승인과 거부의 개수를 따져서 다수결 쪽으로 처리
         * UnanimousBased   : 하나라도 거부가 있으면 거부 처리
         */
        filterSecurityInterceptor.setAccessDecisionManager(affirmativeBased());
        filterSecurityInterceptor.setAuthenticationManager(authenticationManagerBean());    // 인증매니저

        return filterSecurityInterceptor;
    }

SecurityResourceService 클래스 경우 DB로부터 조회해온다.

        // DB로부터 권한과 자원정보를 가져온다.
        LinkedHashMap<RequestMatcher,List<ConfigAttribute>> result = new LinkedHashMap<>();
        List<Resources> resourcesList = userMapper.selectResource();  // Resources 데이터 전부 가져오기
        List<RoleResources> roleResources = userMapper.selectRoleResource();  // RoleResources 데이터 전부 가져오기

        for (int i = 0; i < resourcesList.size(); i++ ) {
           List<ConfigAttribute> configAttributeList = new ArrayList<>();
           Long resourceId = resourcesList.get(i).getResourceId();
           for (int j = 0; j < roleResources.size(); j++ ) {
              if (roleResources.get(j).getResourceId() == resourceId) {
                 configAttributeList.add(new SecurityConfig(roleResources.get(j).getRoleName()));
              }
           }

           if (configAttributeList.size() > 0) {
              result.put(new AntPathRequestMatcher(resourcesList.get(i).getResourceName()), configAttributeList);
           }
        }

그리고 유저별 권한에 따라 접근금지 페이지는 핸들러를 설정하여 커스텀 페이지를 만들면 되겠다.

Security config()에 추가

        .and()
           	.exceptionHandling()
           	.accessDeniedHandler()  // 권한 인증 실패시 처리할 핸들러
private AccessDeniedHandler accessDeniedHandler() {
        CustomAccessDeniedHandler accessDeniedHandler = new CustomAccessDeniedHandler();
        accessDeniedHandler.setErrorPage("/denied");
        return accessDeniedHandler;
    }

+++
추가로 필터를 이용해 동적으로 권한을 구성하는데 있어서, 전체적인 소스를 참고할수 있는 깃헙 주소다
https://github.com/KMSKang/basicsecurity

profile
노옵스를향해

0개의 댓글