kon*_*ack 5 grails spring spring-security
我有一个示例类来测试@PreAuthorize注释,它看起来或多或少像这样:
class BankService {
@PreAuthorize("hasCustomRole('ROLE_CUSTOM') or hasRole('ROLE_EXAMPLE')")
Double getAccountBalance(Integer accountNumber) {
return 1234;
}
@PreAuthorize("#accountNumber > 400")
int getValue(Integer accountNumber) {
return 1234;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以hasCustomRole(String expression)在@PreAuthorize注释中注意到,我正在添加:
public class CustomSecurityExpressionRoot extends SecurityExpressionRoot {
public CustomSecurityExpressionRoot(Authentication auth) {
super(auth);
}
public boolean hasCustomRole(String expression) {
return /* some magic */;
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我正在DefaultMethodSecurityExpressionHandler以下列方式进行扩展:
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
public CustomMethodSecurityExpressionHandler() {
super();
}
@Override
public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) {
StandardEvaluationContext ctx = (StandardEvaluationContext) super.createEvaluationContext(auth, mi);
ctx.setRootObject(new CustomSecurityExpressionRoot(auth));
return ctx;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,一切都包含在resources.groovy:
beans = {
/* ... some stuff ... */
xmlns security:'http://www.springframework.org/schema/security'
security.'global-method-security'('pre-post-annotations': 'enabled') {
security.'expression-handler'(ref: 'expressionHandler')
}
expressionHandler(my.package.plugin.security.expression.CustomMethodSecurityExpressionHandler)
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我从中删除安全部分resources.groovy,我自然会失去使用该hasCustomRole()方法的能力,但以下工作原理:
assert bankService.getValue(500) == 1234
Run Code Online (Sandbox Code Playgroud)
但是,如果我注入我自己的实现,前面的语句会导致:
Access is denied
org.springframework.security.access.AccessDeniedException: Access is denied
Run Code Online (Sandbox Code Playgroud)
经过进一步调查,我发现:
prepost.PrePostAnnotationSecurityMetadataSource Looking for Pre/Post annotations for method 'getValue' on target class 'class my.package.plugin.security.test.BankService'
prepost.PrePostAnnotationSecurityMetadataSource @org.springframework.security.access.prepost.PreAuthorize(value=#accountNumber > 400) found on specific method: public int my.package.plugin.security.test.BankService.getValue(java.lang.Integer)
method.DelegatingMethodSecurityMetadataSource Adding security method [CacheKey[my.package.plugin.security.test.BankService; public int my.package.plugin.security.test.BankService.getValue(java.lang.Integer)]] with attributes [[authorize: '#accountNumber > 400', filter: 'null', filterTarget: 'null']]
aopalliance.MethodSecurityInterceptor Secure object: ReflectiveMethodInvocation: public int my.package.plugin.security.test.BankService.getValue(java.lang.Integer); target is of class [my.package.plugin.security.test.BankService$$EnhancerByCGLIB$$c590f9ac]; Attributes: [[authorize: '#accountNumber > 400', filter: 'null', filterTarget: 'null']]
aopalliance.MethodSecurityInterceptor Previously Authenticated: org.springframework.security.authentication.TestingAuthenticationToken@b35bafc3: Principal: test; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_TELLER
method.MethodSecurityEvaluationContext Unable to resolve method parameter names for method: public final int my.package.plugin.security.test.BankService$$EnhancerByCGLIB$$c590f9ac.getValue(java.lang.Integer). Debug symbol information is required if you are using parameter names in expressions.
Run Code Online (Sandbox Code Playgroud)
有趣的是Debug symbol information is required if you are using parameter names in expressions.,这表明编译的类没有关于变量名的调试信息.但如果我不注射自己的豆子,一切都很好.
可能是缺少调试信息的原因,以及如何解决它?
它是Grails插件,为Grails 2.0.4开发,使用版本为1.2.7.3的spring-security-core插件,版本为1.1的spring-security-acl插件和Spring Security 3.0.7.RELEASE.
编辑:
为了使问题更有趣,这是我后来发现的:如果你查看.class文件,那么"缺失"的调试信息实际上就存在了javap.所以类正确编译,但Spring反正抱怨......
我解决了这个问题,但是,我不确定为什么我收到的日志中的异常和消息与问题相差甚远。
我犯了一个错误,假设grails-app/conf/spring/resources.groovy可以以与使用 Grails 构建的应用程序类似的方式使用它。尽管文档没有明确说明配置的 beansresources.groovy在这种情况下不起作用,但它指出resources.groovy(以及其他一些文件)将默认从打包中排除。
它没有解释运行测试时的奇怪行为,但它不是这种配置的好地方。
将 Spring Security 配置移至resources.groovy插件描述符后,按以下方式进行:
class MyOwnGrailsPlugin {
/* ... some stuff ... */
def doWithSpring = {
/* ... some spring stuff ... */
xmlns security:'http://www.springframework.org/schema/security'
security.'global-method-security'('pre-post-annotations': 'enabled') {
security.'expression-handler'(ref: 'expressionHandler')
}
expressionHandler(my.package.plugin.security.expression.CustomMethodSecurityExpressionHandler)
}
}
Run Code Online (Sandbox Code Playgroud)
一切正常并且测试通过。
| 归档时间: |
|
| 查看次数: |
753 次 |
| 最近记录: |