Tôi có một lớp dụ để kiểm tra @PreAuthorize
chú thích, trông nhiều hơn hoặc ít hơn như thế này một:"thông tin symbol gỡ lỗi là cần thiết (...)" Sau khi chích sửa đổi mùa xuân thực hiện ngôn ngữ biểu thức an ninh
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;
}
}
Bạn có thể nhận thấy hasCustomRole(String expression)
trong @PreAuthorize
chú thích, mà tôi thêm vào:
public class CustomSecurityExpressionRoot extends SecurityExpressionRoot {
public CustomSecurityExpressionRoot(Authentication auth) {
super(auth);
}
public boolean hasCustomRole(String expression) {
return /* some magic */;
}
}
Ngoài ra, tôi đang mở rộng DefaultMethodSecurityExpressionHandler
theo cách sau:
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;
}
}
Cuối cùng, tất cả mọi thứ được gói trong 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)
}
Bây giờ, nếu tôi loại bỏ các phần an ninh từ resources.groovy
, tôi tự nhiên mất khả năng sử dụng phương pháp hasCustomRole()
, nhưng các công việc sau:
assert bankService.getValue(500) == 1234
Nhưng nếu tôi tiêm thực hiện của riêng tôi, báo cáo kết quả trước đó gây ra:
Access is denied
org.springframework.security.access.AccessDeniedException: Access is denied
Sau khi nghiên cứu thêm Tôi thấy điều này:
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.spr[email protected]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.
Phần thú vị là Debug symbol information is required if you are using parameter names in expressions.
, điều này gợi ý rằng lớp được biên dịch mà không cần gỡ lỗi thông tin về tên biến. Nhưng tất cả mọi thứ hoạt động tốt nếu tôi không tiêm đậu của riêng tôi.
Điều gì có thể là lý do cho thông tin gỡ lỗi còn thiếu và cách khắc phục?
Đó là một plugin Grails, được phát triển cho Grails 2.0.4, sử dụng plugin lõi-bảo mật mùa xuân ở phiên bản 1.2.7.3, plugin spring-security-acl tại phiên bản 1.1 và Spring Security 3.0.7.RELEASE.
EDIT:
Để làm cho vấn đề thú vị hơn, đây là những gì tôi phát hiện ra sau đó: sự "mất tích" thông tin gỡ lỗi thực sự ở đó, nếu bạn nhìn vào .class
file với javap
. Vì vậy, các lớp học được biên dịch một cách chính xác, nhưng Spring vẫn phàn nàn ...