gpt4 book ai didi

Grails 自定义安全评估器

转载 作者:行者123 更新时间:2023-12-02 07:48:02 27 4
gpt4 key购买 nike

我正在开发一个必须执行对象级安全检查的应用程序,并且检查将由服务进行,因为它需要对单独的应用程序进行 REST 调用。因此,我无法使用 Spring Security 角色或 ACL,因为这些信息都不会本地存储在应用程序中。我正在尝试找到一种优雅的方法来处理这个问题,以下是我能想到的两个选项:

1) 创建将检查权限的自定义注释

2)扩展 Spring 安全注释权限检查(可能使用权限评估器?),让我编写检查访问的逻辑

对于#1,我创建了一个自定义注释,并使用过滤器来读取注释并检查访问权限,尽管这似乎更脆弱,并且只会为我提供对 Controller 操作的保护,而且最好也保证安全还有其他服务。

我找到了一些信息,但没有完整的。

THIS讲的是自定义ACL,但只是为了一个新的权限,不控制逻辑

THIS谈论使用 SpEL,但我想在方法运行之前进行检查,以确保不会发生未经授权的影响。

THIS似乎是最接近我想要做的,但特定于 Spring Security 而不是 Grails - 我最大的挑战是将 applicationContext.xml 中的信息转换为 resources.groovy

预先感谢您提出的任何建议或建议!

最佳答案

您应该能够使用 spring security 和 grails 轻松完成此操作。

我过去使用以下两种方法来完成类似的任务。两者都需要 spring security ACL 插件,该插件提供 @PreAuthorize@PostAuthorize 注释。

自定义权限评估器

您可以在安全注释中使用 hasPermission() 方法并创建自定义 PermissionEvaluator。在代码中,它看起来像这样:

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

hasPermission() 调用由 spring security 路由到 PermissionEvaluator。要编写自己的实现,您必须实现 PermissionEvaluator 接口(interface):

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 的bean。您可以通过在 conf/spring/resources.groovy 中添加以下行来完成此操作:

beans = {

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

myPermissionEvaluator(MyPermissionEvaluator)

}

resources.groovy中,您可以定义bean,就像使用spring时在applicationContext.xml中所做的那样。上面几行创建了一个 MyPermissionEvaluator 类型的 bean,其名称为 myPermissionEvaluator。 Spring Securities expressionHandler bean 被类型为 MyExpressionHandler 的 bean 覆盖。其他依赖项是从spring security ACL插件的配置文件中复制的。

安全注释中的服务调用

如果 hasPermission() 方法的设计不能满足您的所有要求,您可以使用简单的服务调用。 @PostAuthorize@PreAuthorize 注释使用 SPEL 来计算表达式。在 SPEL 中,您可以使用 @ 符号来访问 bean。例如:

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

这会调用名为 securityService 的 bean 的 canAccess 方法,并将方法参数传递给它。

要使用此方法,您必须注册 BeanResolverEvaluationContext 。为此,您必须覆盖 DefaultMethodSecurityExpressionHandler这是由 spring security ACL 插件配置的。

这可能如下所示:

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 是一个简单的接口(interface),它将 bean 名称解析为 bean 实例:

class GrailsBeanResolver implements BeanResolver {

GrailsApplication grailsApplication

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

}

最后将 bean 添加到 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')
}

更新(2013-10-22):最近我写了一篇blog post正是关于这一点,它提供了一些额外的信息。

关于Grails 自定义安全评估器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17789822/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com