mnd*_*mnd 5 grails spring-security
我正在开发一个必须进行对象级安全检查的应用程序,并且检查将由服务进行,因为它需要对单独的应用程序进行REST调用.因此,我无法使用Spring Security角色或ACL,因为这些信息都不会存储在应用程序的本地.我正试图找到一种优雅的方式来处理这个,这里有两个我能想到的选择:
1)创建将检查权限的自定义注释
2)扩展Spring安全注释权限检查(可能使用Permission Evaluator?),它允许我编写用于检查访问的逻辑
#1我已经创建了一个自定义注解和使用过滤器来读取注释和检查访问,虽然这似乎更脆,只会给我控制器动作保护我,这将是很好也确保其他服务好.
我发现了一些信息,但没有完整.
这谈到了自定义ACL,但仅限于新的权限,而不是控制逻辑
这是关于使用SpEL的,但我希望在方法运行之前进行检查,以确保不会发生任何未经授权的影响.
这似乎是我最接近我想做的,但是特定于Spring Security而不是Grails - 我最大的挑战是将applicationContext.xml中的信息转换为resources.groovy
提前感谢您提出的任何建议或建议!
mic*_*cha 10
你应该能够用弹簧安全和grails做到这一点,没有太多麻烦.
我过去使用以下两种方法来完成类似的任务.两者都需要弹簧安全ACL插件,它提供@PreAuthorize和@PostAuthorize注释.
自定义PermissionEvaluator
您可以使用hasPermission()安全注释中的方法并创建自定义PermissionEvaluator.在代码中,这看起来像这样:
@PreAuthorize("hasPermission(#myObject, 'update')")
public void updateSomething(myObject) {
..
}
Run Code Online (Sandbox Code Playgroud)
将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
}
}
Run Code Online (Sandbox Code Playgroud)
要注册您,PermissionEvaluator您必须覆盖名为的bean expressionHandler.您可以通过添加以下行来执行此操作conf/spring/resources.groovy:
beans = {
expressionHandler(MyExpressionHandler) {
parameterNameDiscoverer = ref('parameterNameDiscoverer')
permissionEvaluator = ref('myPermissionEvaluator') // your PermissionEvaluator
roleHierarchy = ref('roleHierarchy')
trustResolver = ref('authenticationTrustResolver')
}
myPermissionEvaluator(MyPermissionEvaluator)
}
Run Code Online (Sandbox Code Playgroud)
resources.groovy你可以在内部定义bean,就像applicationContext.xml使用spring时一样.上面的行创建了一个MyPermissionEvaluator带有bean名称的bean类型myPermissionEvaluator.Spring证券expressionHandlerbean被类型的bean覆盖MyExpressionHandler.其他依赖项是从spring security ACL插件的配置文件中复制的.
服务调用安全注释
如果hasPermission()方法的设计不能满足您的所有要求,则可以使用简单的服务调用.在@PostAuthorize和@PreAuthorize注释使用SPEL来计算表达式.在SPEL中,您可以使用@符号来访问bean.例如:
@PreAuthorize("@securityService.canAccess(#myObject)")
public void doSomething(myObject) {
..
}
Run Code Online (Sandbox Code Playgroud)
这将调用canAccessbean命名securityService的方法,并将方法参数传递给它.
要使用这个方法,你必须注册一个BeanResolver上EvaluationContext.为此,您必须覆盖由spring security ACL插件配置的DefaultMethodSecurityExpressionHandler.
这可能如下所示:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
BeanResolver 是一个简单的接口,它将bean名称解析为bean实例:
class GrailsBeanResolver implements BeanResolver {
GrailsApplication grailsApplication
@Override
public Object resolve(EvaluationContext evaluationContext, String beanName) throws AccessException {
return grailsApplication.mainContext.getBean(beanName)
}
}
Run Code Online (Sandbox Code Playgroud)
最后将豆子添加到resources.groovy:
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')
}
Run Code Online (Sandbox Code Playgroud)
更新(2013-10-22):最近我写了一篇关于这个的博客文章,提供了一些额外的信息.
| 归档时间: |
|
| 查看次数: |
1653 次 |
| 最近记录: |