관리 메뉴

IT.FARMER

Spring Security 동적 권한 할당 본문

Spring/Spring Security

Spring Security 동적 권한 할당

아이티.파머 2016. 10. 19. 16:47
반응형

Spring Security RBAC 모델의 멋진 권한 컨트롤 시큐어 프레임웍임니다.

이에 이녀석을 가지고 동적 권한 할당에 대해 예전에도 생각해 본적이 있었 습니다.
 
내용은  관리자가 환경설정에서 PERMISSON을 수정하여,  접속된 사용자에게도 바로 적용되는 것입니다.
 
접속된 사용자 별로 SecurityContext에서 Authority 객체에 접근하여, 생성한 GrantedAuthority를 restset하고 새롭게 부여해주는방법과.
로그인 할때 GrantedAuthority 없이 항시 urlCall 혹은 methdo 호출 마다 어떤 필터에서 이미 정의된 ROLE ,url을 이용해서 DB에 값을 확인하고 통과 시켜주는 방법입니다.
 
첫번째 방법은 사용자가 많은 경우 모든 사용자의 권한을 새롭게 부여해줘야 하는 리소스가
두번째는 사용자 액션이 일어날때마다 DB 조회와 권한 체크기 이루어 져야 합니다.
 
실시간 동적권한을 부여 하려면어떤 방법이 더 좋을가요?
혹시 다른 방법이 있다면 추천도 부탁드립니다.
 
사용자에게 로그아웃후에 접근하라고 해야 할까요.
 

* Jsr250

@Secured
@PreAuthority,       : method 안의 인자값 사용가능
@PostAuthority      : 처리후 return 되는 값 사용 가능.
 
* 몇 가지 샘플
 
@PreAuthorize("#c.name == authentication.name")public void doSomething(@P("c") Contact contact);

@PreAuthorize("#contact.name == authentication.name")public void doSomething(Contact contact);

@PreAuthorize("hasPermission(#contact, 'admin')")public void deletePermission(Contact contact, Sid recipient, Permission permission);
 
 

Spring Security Reference

In Spring Security 3.0, the codebase was sub-divided into separate jars which more clearly separate different functionality areas and third-party dependencies. If you use Maven to build your project, these are the modules you should add to your pom.xml. Ev

docs.spring.io

 
 
ROLE를 GrantedAuthority (SimpleGrantedAuthority)에 Connection<> 객체로 추가한 후 Permission을 별도로 체크해 보려 하니, 
퍼미션을 추가한 부분이 없다. 여러 가지 샘플을 보니, 같은 Authentication에 add 하는 방식을 사용하고 있다.
 
ROLE별로 별도의 Permission을 가진 녀석을 처리하고 싶다보니 PermissionEvaluator 를  상속받아 CustomPermissionEvaluator
만들어 해당 ROLE의 PERMISSION 을 불러와 있는지 체크해 보는것이다.
 
퍼미션에볼루터를 기본으로 가진 DenyPermissionEvaluator를 보면 false로 되어 있다.
이에 환경설정을 해주도록 한다.
 
@Secured ,@pre.PostAuthority 를 사용하기 위한 활성화 , 기본 false
* 환경설정 파일  MethodSecurityConfig
 
@Configuration
@EnableGlobalMethodSecurity(securedEnabled=true,prePostEnabled=true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
     
     @Override
     protected MethodSecurityExpressionHandler createExpressionHandler() {
          
          DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
          expressionHandler.setPermissionEvaluator(customPermissionEvaluator());
          
          return expressionHandler;
     }
     
     
     @Bean
     public CustomPermissionEvaluator customPermissionEvaluator() {
          return new CustomPermissionEvaluator();
     }
}
 
 
 
* CustomPermissionEvaluator 는 다음과 같다.
public class CustomPermissionEvaluator implements PermissionEvaluator {    
     private final Logger logger = LoggerFactory.getLogger(getClass());
     
     @Autowired RoleJpaRepository roleJpaRepository;
     /*
      * Permisstion Table에서 Permission 정보를 체크하기 위해 사용한다.
      * (non-Javadoc)
      * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
      */
     @Override
     public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
          logger.debug("ACL Permission ");
          
          BooleanBuilder builder = new BooleanBuilder();
          builder.and(QRoleDto.roleDto.roleId.in(authentication.getAuthorities().stream()
                             //.filter(simpleGrantedAuthority-> !simpleGrantedAuthority.getAuthority().equals(""))
                             .findAny().get().getAuthority()
                       ));
          
          long permissionCount = roleJpaRepository.count(builder);
          if(permissionCount >= 1) {
              return true;
          }
          return false;
     }
     @Override
     public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
          // TODO Auto-generated method stub
          return false;
     }
}
 
ACL (Access Control Level)을 수정해서 사용중이지만,
실시간 RBAC(Role Base Access Control)모델이 적용되지 않더라도 
로그인 할때만 해당 데이터를 받아 사용하느게 더 좋을것 같다.

 

반응형