2011-05-16 3 views
2

스프링 시큐리티 또는 시로 (Shiro)를 사용하여 "인 타이틀먼트"개념을 처리하는 가장 좋은 방법에 대한 의견을 듣고 싶습니다.스프링 보안 또는 시로 (Shiro)를 사용하는 인시던트에 대한 모범 사례

예를 들어, 말,이 같은 서명이있는 JAX-RS 엔드 포인트 상상 :

@Secured(AUTHORIZED_USER) 
public AccountDetails getAccountDetails(String accountId) { ... } 

또는 사용 :

AccountDetails getAccountDetails(String accountId); 

봄 보안 사용을, 내가 좋아 구현 주석을 달 수있다 Shiro,

@RequiresAuthentication 
public AccountDetails getAccountDetails(String accountId) { ... } 

그러나 내가 찾고있는 것은 "best pra 사용자가 특정 계정 ID에 액세스 할 수있는 권한을 갖는지 확인하는 방법에 대해 "ctices"를 사용합니다 ("권한 부여 관리"라고합니다).

@Secured(AUTHORIZED_USER) 
@AccountEntitled 
public AccountDetails getAccountDetails(@Account String accountId) { ... } 

(봄 보안을 사용하여 완전히 같은 간단하지 날을 친다, 그러나 나는 잘못 싶어요) :

나는 두개의 서로 다른 접근법을 상상할 수있다.

또는, 나는 AccountId 도메인 개체, 현재 보안 컨텍스트에 의해 개최 원칙은 사용자가 해당 계정을 볼 것을 허용하는 경우에만 AccountIdString 선회에 성공 공장을 도입 상상할 수 있었다. 그러나 그것은 조금 지저분 해지기 시작합니다.

전체적으로 나는 여기에 새로운 개념을 발명하고 싶지 않습니다. 이것은 빵 & 버터 물건처럼 보이지만, 모범 사례에 대한 신뢰할만한 권장 사항을 많이 찾지는 못했습니다.

의견을 보내 주셔서 감사합니다.

답변

1

특정 계정에 대한 행 수준 보안을 구현하는 것 같습니다. 이 문제에 대한 잠재적 해결책을 논의하는 다른 Stackoverflow 질문 (How to implement row-level security in Java?Database independent row level security solution)이 있습니다. 또한 첫 번째 대답에서 제공된 링크는 Row Level Security with Spring and Hibernate 구현에 대해 설명합니다. 그러나 상위 랭킹 응답에서는 데이터베이스 수준에서 행 수준 보안을 직접 구현하는 것이 좋습니다.

시로와 함께 일하면서 할 수 있다고 말할 수 있습니다. 그러나 설명하는 기능 유형을 수용하기 위해 자체 보안 구조 (영역, 권한, 주석)를 구현해야합니다. 하나의 접근법은 메소드가 권한 검사를 필요로 함을 나타내는 마지막 예제에서와 유사한 주석을 추가하는 것입니다. 이 주석은 적절한 권한을 생성 한 다음 보안 프레임 워크를 호출하여 권한을 확인하는 인터셉터에 연결됩니다.

다음과 같이 보일 것입니다.

방법 :

@RequiresAuthorization 
@Entitled 
public AccountDetails getAccountDetails(@Account String accountId) {...} 

인터셉터 :

@Interceptor 
@Entitled 
public class EntitledInterceptor { 
    @AroundInvoke 
    public void interceptOrder(InvocationContext ctx) { 
     // return type is AccountDetails 
     // parameter[0] is acccoundId 
     Permission p = new CustomPermission(context.getMethod().getReturnType(), 
              ctx.getParameters()[0]); 
     if(SecurityUtils.getSubject().isPermitted(p)){ 
      return ctx.proceed(); 
     } else { 
     throw new RowLevelSecurityException("No access!"); 
     } 
} 

영역 :

public boolean isPermitted(SubjectPrincipals principal, Permission p){ 
    if(p instanceof CustomPermission){ 
     CustomPermission cp = (CustomPermission) p; 
     Class<?> type = cp.getType(); //AccountDetails 
     Integer id = cp.getId(); //accountId 
     Integer userId = principal.getPrimaryPrincipal(); //or username 
     customPermissionCheckingLogic(userId, type, id); 
    } 
} 

분명이 구현은 CDI에 의존하고 당신이 무엇을 테이블 (들)을 결정하는 방법을 필요로 제공된 객체 유형을 기반으로 확인하십시오 (JPA 주석은 이와 관련하여 작동합니다). 또한 여기에서했던 것보다 직접/네이티브 권한 기능을 제공하기 위해 Shiro의 주석 검색에 연결하는 방법이있을 수 있습니다.

Documentation on CDI interceptors.

관련 문제