2014-05-09 22 views
5

Tôi đang triển khai hạn chế/cấp phép phương thức (trên dịch vụ REST) bằng Bảo mật mùa xuân.
Tôi đã sử dụng ngôn ngữ biểu thức mùa xuân và đã thực hiện Đánh giá biểu thức tùy chỉnh.Trả lại JSON về yêu cầu dịch vụ REST trái phép bằng cách sử dụng Spring Security 'hasPermission()'

Nó hoạt động tốt cho tôi. Tuy nhiên, nếu người dùng trái phép cố gắng truy cập dịch vụ, nó sẽ phản hồi bằng trang đăng nhập. Vì ứng dụng của tôi là REST chỉ dựa trên, tôi chỉ muốn trả lại dữ liệu JSON cho tất cả các yêu cầu.

Làm thế nào để làm cho nó trở về JSON thay vì trang đăng nhập (ví dụ: {status : Denied})?

Đây là mã số câu liên quan:

CustomEvaluator

public boolean hasPermission(Authentication authentication, Object userId, Object permissionId) { 
     List<String> permList = new MyDAO().getPermissionsForUser((String) userId); 
     if(permList.contains(((String) permissionId))){ 
      return true; 
     }else{ 
      return false; 
     } 
    } 

Dịch vụ

@PreAuthorize("hasPermission(#userId, '3')") 
    public String testAuthorization(Object obj, String userId){ 

     System.out.println("Has access to the service method...."); 

     return "success"; 
    } 

khiển

public @ResponseBody String testAuthorization(Object o,@RequestParam("userId") String userId){ 
     System.out.println("User ID = "+userId); 
     String abc = service.testAuthorization(o,userId); 
     return "{\"status\":\"success\"}"; 
    } 

mùa xuân-security.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:security="http://www.springframework.org/schema/security" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
      http://www.springframework.org/schema/security 
      http://www.springframework.org/schema/security/spring-security-3.0.xsd"> 


    <security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled"> 
     <security:expression-handler ref="expressionHandler"/> 
    </security:global-method-security> 

    <!-- This is where we configure Spring-Security --> 
    <security:http auto-config="true" use-expressions="true" access-denied-page="/auth/auth/denied" > 
     <security:intercept-url pattern="/auth/auth/login" access="permitAll"/> 
     <security:intercept-url pattern="/auth/main/admin" access="hasRole('ROLE_ADMIN')"/> 
     <security:intercept-url pattern="/auth/main/common" access="hasRole('ROLE_USER')"/> 


    </security:http> 

    <security:authentication-manager> 
     <security:authentication-provider user-service-ref="customUserDetailsService"> 
      <security:password-encoder ref="passwordEncoder"/> 
     </security:authentication-provider> 
    </security:authentication-manager> 

    <!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database --> 
    <bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/> 

    <!-- A custom service where Spring will retrieve users and their corresponding access levels --> 
    <bean id="customUserDetailsService" class="com.cjl.security.service.CustomUserDetailsService"/> 

    <bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> 
     <property name="permissionEvaluator" ref="permissionEvaluator"/> 
    </bean> 

    <bean id="permissionEvaluator" class="com.cjl.security.evaluators.MethodPermissionEvaluator"/> 


</beans> 

Trả lời

5

gì đang xảy ra là một AccessDeniedException đang được ném, vì vậy bạn muốn cấu hình hệ thống của bạn để đánh chặn mà ngoại lệ và thay vào đó trở lại JSON.

Bạn có thể thiết lập phương thức @ExceptionHandler trong bộ điều khiển của mình để bắt số AccessDeniedException. Tuy nhiên, bạn có thể muốn làm điều tương tự trong tất cả các bộ điều khiển, vì vậy nếu bạn đang sử dụng Spring 3.2, bạn có thể sử dụng chú thích @ControllerAdvice trên một lớp 'lời khuyên' riêng biệt và sau đó bao gồm phương thức @ExceptionHandler trong đó.

@ControllerAdvice 
public class ExceptionControllerAdvice { 

    @ExceptionHandler(AccessDeniedException.class) 
    @ResponseBody 
    public String exception(AccessDeniedException e) { 
     return "{\"status\":\"access denied\"}"; 
    } 
} 
+0

Tôi đang sử dụng phiên bản bảo mật mùa xuân 3.0.5. Tôi đã thêm @ExceptionHandler (AccessDeniedException.class) vào bộ điều khiển của mình. Vẫn nhận được cùng một trang đăng nhập. –

+0

Xin lỗi, lỗi của tôi. Nó hiện đang hoạt động. Trong phiên bản 3.0.5, nếu tôi phải xử lý cùng một ngoại lệ trong một bộ điều khiển khác, cách thức là gì? Sao chép xử lý ngoại lệ là cách duy nhất? –

+0

Bạn có thể sao chép trình xử lý hoặc bạn có thể tạo abstractController mà tất cả các bộ điều khiển khác của bạn mở rộng. Bạn cũng có thể tạo ra một khía cạnh mà nó tuyên bố xử lý cho tất cả các bộ điều khiển của bạn, mặc dù tôi thừa nhận tôi đã không thử nó. – DavidA

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