2014-04-22 3 views
1

스프링 보안에 대한 내 자신의 PermissionEvaluator를 작성 중이며, 내가하려고하는 일 중 하나는 보호하고있는 메소드의 이름을 파악하는 것입니다.사전/사후 권한 부여 메소드 이름 얻기

예를 들어, 그림에서 메소드 이름없이 내가 좋아하는 뭔가가 있습니다

postAuthorize("hasPermission(returnObject,'read')") 
Event getEvent(int evendId) { 
... 
} 

public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { 
    if(targetDomainObject instanceof Event) { 

     return hasPermission(authentication, targetDomainObject, permission); 
    } 
    return targetDomainObject == null; 
} 

을하지만 또한 메소드 이름 "getEvent"는 hasPermission 사용할 수 있어야합니다. 다음과 같이 수동으로 hasPermission 호출을 전달하여이 작업을 수행 할 수 있습니다.

@PostAuthorize("hasPermission(new com.example.AuthZObject(returnObject,'getEvent'),'read')") 
Event getEvent(int eventId); 

더 많은 자동화 된 방법이 있습니까?

답변

1

@Ralph 여기에 올바른 아이디어가 많이 있습니다. 첫 번째 단계는 메서드를 저장하고 표현식을 평가하는 데 사용할 수있는 MethodSecurityExpressionOperations의 사용자 지정 구현을 만드는 것입니다. 예를 들면 다음과 같습니다.

public class MyMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations { 
    private Object filterObject; 
    private Object returnObject; 
    private Object target; 
    private Method method; 

    public MyMethodSecurityExpressionRoot(Authentication a) { 
     super(a); 
    } 

    // allow the method to be set  
    public void setMethod(Method m) { 
     this.method = m; 
    } 

    // optionally expose the method to be accessed in expressions  
    public Method getMethod() { 
     return method; 
    } 

    // create a method that will perform the check with 
    // the method name transparently for you  
    public boolean hasMethodPermission(Object target, Object permission) { 
     boolean result = false; 

     // do your calculations using the method member variable 
     // i.e. method.getName() and the arguments passed in 
     // of course you could delegate to another object if you want 
     // i.e. 
     // return hasPermission(new com.example.AuthZObject(target,method.getName()),permission)); 
     // or you could do the logic right here 

     return result; 
    } 

    // implement the interface and provide setters 

    public void setFilterObject(Object filterObject) { 
     this.filterObject = filterObject; 
    } 

    public Object getFilterObject() { 
     return filterObject; 
    } 

    public void setReturnObject(Object returnObject) { 
     this.returnObject = returnObject; 
    } 

    public Object getReturnObject() { 
     return returnObject; 
    } 

    public void setThis(Object target) { 
     this.target = target; 
    } 

    public Object getThis() { 
     return target; 
    } 
} 

다음으로 확장하여 사용자 정의 표현식 루트를 사용하십시오.

public class MySecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler{ 

    @Override 
    protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation){ 
     MyMethodSecurityExpressionRoot root = new MyMethodSecurityExpressionRoot(authentication); 
     root.setThis(invocation.getThis()); 
     root.setPermissionEvaluator(getPermissionEvaluator()); 
     root.setTrustResolver(new AuthenticationTrustResolverImpl()); 
     root.setRoleHierarchy(getRoleHierarchy()); 
     root.setMethod(invocation.getMethod()); 
     return root; 
    } 
} 

당신이 MySecurityExpressionHandler을 구성하고 나면, 다음 사용할 수 있어야한다 : (MethodSecurityExpressionOperations을 확장 작업)

@PostAuthorize("hasMethodPermission(returnObject,'read')") 
Event getEvent(int eventId); 
1

이것이 가능한지는 잘 모르겠지만, DefaultMethodSecurityExpressionHandler을 살펴 봐야합니다. 이 클래스는이 두 가지 방법이 있습니다

public final EvaluationContext createEvaluationContext(Authentication authentication, T invocation) { 
    SecurityExpressionOperations root = createSecurityExpressionRoot(authentication, invocation); 
    StandardEvaluationContext ctx = createEvaluationContextInternal(authentication, invocation); 
    ctx.setBeanResolver(br); 
    ctx.setRootObject(root); 

    return ctx; 
} 

protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) { 
    MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(authentication); 
    root.setThis(invocation.getThis()); 
    root.setPermissionEvaluator(getPermissionEvaluator()); 
    root.setTrustResolver(trustResolver); 
    root.setRoleHierarchy(getRoleHierarchy()); 

    return root; 
} 

나는 당신이 필요로하는 추가 필드와 클래스 MethodSecurityExpressionOperations을 확장 할 필요가 있다고 생각하고 당신이 DefaultMethodSecurityExpressionHandler를 서브 클래스하고 반환 있도록 MethodSecurityExpressionOperations를 확장하는 createSecurityExpressionRoot 방법을 교체해야 채워진 필드가있는

그런 다음이 추가 필드에 액세스 할 수있는 확장 MethodSecurityExpressionOperations에 새 메서드를 추가 할 수 있습니다.

+0

감사 랄프, 내가 뭔가를하는 과정에서 오전하지만, [히트]있다 (http://stackoverflow.com/questions/23237117/creating-custom-postauthorize-method-in-spring-security) 문제에 대한 또 다른 벽 –

관련 문제