2012-11-27 18 views
5

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 ...

Trả lời

0

Tôi đã khắc phục vấn đề, tuy nhiên, tôi không chắc chắn lý do tại sao các ngoại lệ và thư trong nhật ký mà tôi nhận được cho đến nay vẫn gặp vấn đề.

Tôi đã phạm một sai lầm giả định rằng grails-app/conf/spring/resources.groovy có thể được sử dụng theo cách tương tự như trong các ứng dụng được xây dựng bằng Grails. Và mặc dù tài liệu không rõ ràng rằng các bean được cấu hình trong resources.groovy sẽ không hoạt động trong trường hợp này, nó tuyên bố rằng resources.groovy (trong số một số tệp khác) theo mặc định sẽ bị loại trừ khỏi bao bì.

Nó không giải thích được hành vi lạ trong khi chạy thử nghiệm, nhưng nó không phải là một nơi tốt cho loại cấu hình này.

Sau khi di chuyển các cấu hình Spring Security từ resources.groovy vào mô tả plugin, theo cách sau:

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) 
    } 
} 

tất cả mọi thứ hoạt động tốt và thử nghiệm đi.

Các vấn đề liên quan