2013-07-22 3 views
3

객체 레벨의 보안 검사를해야하는 응용 프로그램에서 작업 중이며 별도의 응용 프로그램에 REST 호출을해야하기 때문에 서비스가 검사를 수행합니다. 이 때문에 나는이 정보가 앱에 로컬로 저장되지 않기 때문에 스프링 보안 역할이나 ACL을 사용할 수 없습니다.Grails 커스텀 보안 평가자

1)) 권한

2

을 확인 봄 보안 주석 권한 체크를 확장하는 사용자 정의 주석을 작성 : 나는의 내가 생각할 수있는 두 가지 옵션이 여기에이 처리하는 우아한 방법을 찾기 위해 노력하고있어 (아마도 권한 평가자가 있습니까?)

# 1 저는 맞춤 어노테이션을 작성했고 필터를 사용하여 어노테이션을 읽고 액세스를 확인했습니다. 컨트롤러 동작에 대한 보호 만 제공하고 다른 서비스도 보호하는 것이 좋습니다.

나는이 정보 조각을 찾았지만 아무 것도 완성하지 못했습니다. ACL을 정의하지만 새로운 권한, SpEL을 사용에 대한

THIS 회담 논리를 제어하지,하지만 방법을 실행하기 전에 아무런 영향이지지 않습니다 있는지 확인하기 위해 검사를하고 싶습니다에 대한

THIS 회담 승인되지 않은 장소.

THIS

내가 무엇을 원하는에 가장 가까운 것으로 보인다,하지만 봄 보안 및하지 Grails는 특정입니다 - 내 가장 큰 도전은 사전에 resources.groovy에 applicationContext.xml에

감사 정보를 변환한다 당신이 가질 수있는 제안이나 조언!

+0

확실하지가 가장 좋은 방법입니다,하지만 난 필터를 통해 수행 한 대한 보안 당신은 말하고있다. –

+0

응답 @ JamesKleeh 주셔서 감사합니다. 컨트롤러 동작 만 필터링하는 데 문제가 있습니까? – mnd

+0

아니, 나는 그런 식으로 할 수없는 일에 빠지지 않았다. 그 밖의 무엇을 확보 할 수 있습니까? 정적 콘텐츠? –

답변

8

스프링 보안과 grails를 사용하면 별 어려움없이이 작업을 수행 할 수 있습니다.

나는 유사한 작업을 위해 과거에 다음 두 가지 방법을 사용했습니다. 둘 다 @PreAuthorize@PostAuthorize 주석을 제공하는 봄 보안 ACL 플러그인이 필요합니다.

사용자 정의 PermissionEvaluator는

당신은 보안 주석 내에서 hasPermission() 방법을 사용하여 사용자 정의 PermissionEvaluator을 만들 수 있습니다. 코드 내에서 이것은 다음과 같습니다

@PreAuthorize("hasPermission(#myObject, 'update')") 
public void updateSomething(myObject) { 
    .. 
} 

hasPermission() 통화 봄 보안에 의해 PermissionEvaluator로 라우팅됩니다. 자신의 구현을 작성하려면이 PermissionEvaluator 인터페이스를 구현해야합니다 :

class MyPermissionEvaluator implements PermissionEvaluator { 

    @Override 
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { 
     // your custom logic.. 
    } 

    @Override 
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) { 
     // your custom logic 
    } 
} 

등록하는 PermissionEvaluator 당신이 expressionHandler라는 이름의 빈을 무시해야합니다. 당신은 conf/spring/resources.groovy에 다음 행을 추가하여이 작업을 수행 : 봄을 사용할 때 applicationContext.xml에서하는 것처럼 resources.groovy

beans = { 

    expressionHandler(MyExpressionHandler) { 
     parameterNameDiscoverer = ref('parameterNameDiscoverer') 
     permissionEvaluator = ref('myPermissionEvaluator') // your PermissionEvaluator 
     roleHierarchy = ref('roleHierarchy') 
     trustResolver = ref('authenticationTrustResolver') 
    } 

    myPermissionEvaluator(MyPermissionEvaluator) 

} 

당신은 빈을 정의 할 수 있습니다. 위의 행은 빈 이름이 myPermissionEvaluatorMyPermissionEvaluator 유형의 빈을 작성합니다. 봄 증권 expressionHandler bean은 MyExpressionHandler 유형의 bean으로 대체됩니다.다른 종속성은 스프링 보안 ACL 플러그인의 구성 파일에서 복사됩니다. hasPermission() 방법의 설계가 모든 사용자의 요구 사항이 간단한 서비스가 대신 호출을 사용할 수 achive하지 않는 경우

서비스

보안 주석에 호출합니다. @PostAuthorize@PreAuthorize 주석은 SPEL을 사용하여 표현식을 평가합니다. SPEL에서 @ 기호를 사용하여 빈에 액세스 할 수 있습니다. 예를 들어 :

@PreAuthorize("@securityService.canAccess(#myObject)") 
public void doSomething(myObject) { 
    .. 
} 

securityService라는 이름의 bean의 canAccess 메서드를 호출하고 여기에 메소드 인수를 전달합니다.

당신이 EvaluationContextBeanResolver을 등록해야이 방법을 사용합니다. 이렇게하려면 봄 보안 ACL 플러그인에 의해 구성된 DefaultMethodSecurityExpressionHandler을 무시해야합니다.

이 다음과 같이 할 수 있습니다 resources.groovy에 콩을 추가 마침내

class GrailsBeanResolver implements BeanResolver { 

    GrailsApplication grailsApplication 

    @Override 
    public Object resolve(EvaluationContext evaluationContext, String beanName) throws AccessException { 
     return grailsApplication.mainContext.getBean(beanName) 
    } 

} 

그리고 :

class MyExpressionHandler extends DefaultMethodSecurityExpressionHandler { 

    BeanResolver beanResolver 

    @Override 
    public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) { 
     StandardEvaluationContext ctx = (StandardEvaluationContext) super.createEvaluationContext(auth, mi) 
     ctx.setBeanResolver(beanResolver) // set BeanResolver here 
     return ctx; 
    }  
} 

BeanResolver는 빈 인스턴스에 빈 이름을 확인하는 간단한 인터페이스입니다

expressionHandler(MyExpressionHandler) { 
    parameterNameDiscoverer = ref('parameterNameDiscoverer') 
    permissionEvaluator = ref('permissionEvaluator') 
    roleHierarchy = ref('roleHierarchy') 
    trustResolver = ref('authenticationTrustResolver') 
    beanResolver = ref('beanResolver') // this is your BeanResolver 
} 

// This is the service called within security expressions 
// If you place your service in the grails service folder you can skip this line 
securityService(MySecurityService) 

// this is your BeanResolver 
beanResolver(GrailsBeanResolver) { 
    grailsApplication = ref('grailsApplication') 
} 

UPDAT 전자 (2013년 10월 22일는) : 최근에 나는 몇 가지 추가 정보를 제공하는 정확히 이것에 대해 blog post을 썼다.

+0

감사합니다. @micha! 주석을 달기 위해 (누군가 다른 사람이이 문제에 부딪혔을 때),이 호출은 * controller * 메소드가 아닌 * service * 메소드에서 작동합니다. 그래서 주석을 넣을 곳을주의하십시오. – mnd

관련 문제