Grails Spring Security Expression - 如何访问Method参数 [英] Grails Spring Security Expression - How to access Method parameter

查看:107
本文介绍了Grails Spring Security Expression - 如何访问Method参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Grails的Spring Security插件:
版本:2.0-RC2



控制器我正在使用 @Secured 注释。
有没有办法从spring安全表达式中访问方法参数: #paramName 不适合我。

  @Secured(['ROLE_ADMIN','hasRole('ROLE_USER')&& @ permissionService.updateAllowed(#myInstance)])
def update (Bug myInstance){




问题:myInstance is null! p>

我正在使用的软件:

Grails:2.4.3

Intellij 14

JDK 8

解决方案

我没有注意到你在做这件事一个控制器 - 不支持注释控制器中的方法参数。原因在于,在传统的Spring Security中,注释被应用到Spring Beans并且bean被代理,并且代理在调用方法之前执行安全性检查,并且只在检查通过时调用真正的方法。这对于Spring MVC控制器非常有效,因为它们是常规的Java类,而且在Grails服务中也是如此,因为Grails没有太多的服务添加到服务中 - 它们实际上只是自动注册为Spring Bean的常规Groovy类,而且默认情况下是交易。

但控制器很奇怪。实际上在任何Grails应用程序中都有一个SpringMVC控制器,并且它由Grails在内部创建和使用。它与SpringMVC的其余部分进行交互,并委托给与当前请求的url映射规则最匹配的控制器来完成其工作,并使用它来创建Spring期望的ModelAndView。此外,为了支持数据绑定,在编译过程中会在代码上运行AST转换,这会为每个带有args的方法创建一个无参数方法,这就是Grails内部请求处理代码所调用的方法。它执行数据绑定和类型转换,并调用真实方法来处理请求。



Spring Security支持使用方法args取决于可用的调试信息在编译的代码中,通常这是不可用的,因为它很少需要 - 在编译时,javac为我们连接所有东西,并且通常不需要从方法外部获取方法arg的值。 Grails确实保留了这个调试信息 - 这就是为什么它可以在服务中工作 - 但它看起来像AST不是。也许可以做到这一点,但我不知道它是否会涉及或将涉及什么,并且说实话,对于不会使用太多功能的功能可能会有很多工作。



但是您可以重新进行检查以将 params 传递给服务,并让它查找 Bug 实例,然后进行检查。您可以从服务中访问参数,因此不需要传递任何参数:

  import org.springframework.web。 context.request.RequestContextHolder 
...
def params = RequestContextHolder.requestAttributes.params


Using the Spring Security Plugin for Grails: Version: 2.0-RC2

For my controllers I am using the @Secured annotation. Is there a way to access the method parameter from the spring security expression.#paramName does not work for me.

@Secured(['ROLE_ADMIN',"hasRole('ROLE_USER') && @permissionService.updateAllowed( #myInstance )"])
def update(Bug myInstance) {

The problem: myInstance is null!

Software I am using:

Grails: 2.4.3
Intellij 14
JDK 8

解决方案

I didn't notice that you were doing this in a controller - there's no support for method args in annotated controllers. The reason for this is that in traditional Spring Security, the annotation is applied to Spring Beans and the bean becomes proxied, and the proxy does the security checks before calling the method and only calls the real method if the checks pass. That works well with Spring MVC controllers because they're regular Java classes, and also in Grails services because there isn't much added to services by Grails - they're really just regular Groovy classes that are auto-registered as Spring Beans, and by default are made transactional.

But controllers are weird. There is actually one SpringMVC controller in any Grails app, and it's internally created and used by Grails. It interacts with the rest of SpringMVC, and delegates to the controller that best matches the url mappings rule for the current request to do its work, and it uses that to create the ModelAndView that Spring expects. Additionally, to support databinding, there's an AST transform that runs on your code during compilation which creates a no-arg method for each method with args, and that is what is called from the Grails internal request handling code. It does databinding and type conversions, and calls the "real" method to handle the request.

The support in Spring Security for working with method args depends on debug information being available in the compiled code, and usually this is not available because it's rarely needed - javac connects everything for us at compile time and getting the value of a method arg from outside of the method isn't often needed. Grails does keep that debug info - that's why this works in a service - but it looks like the AST isn't. It might be possible to get that working, but I have no idea if it is or what would be involved, and to be honest it would likely be a lot of work for a feature that wouldn't be used a lot.

But you can rework the check to pass the params to the service and let it lookup the Bug instance and then do its check. You can access the params from the service, so there's no need to pass anything as args:

import org.springframework.web.context.request.RequestContextHolder
...
def params = RequestContextHolder.requestAttributes.params

这篇关于Grails Spring Security Expression - 如何访问Method参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆