簡體   English   中英

使用Spring Security'hasPermission()'對未經授權的REST服務請求返回JSON

[英]Return JSON on unauthorized REST service request using Spring Security 'hasPermission()'

我正在使用Spring安全性實現方法級別的限制/授權(在REST服務上 )。
我已使用spring表達式語言並實現了自定義Expression Evaluator。

對我來說很好。 但是,如果未經授權的用戶嘗試訪問該服務,它將以登錄頁面作為響應。 由於我的應用程序僅基於REST ,因此我只想為所有請求返回JSON數據。

如何使其返回JSON而不是登錄頁面?(例如: {status : Denied}

這是代碼段:

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

服務

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

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

        return  "success";
    }

控制者

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\"}";
    }

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

正在發生的情況是拋出了AccessDeniedException ,因此您需要配置系統以攔截該異常並返回JSON。

您可以在控制器內設置@ExceptionHandler方法,以捕獲AccessDeniedException 但是,您可能想在所有控制器中執行相同的操作,因此,如果您使用的是Spring 3.2,則可以在單獨的“ advice”類上使用@ControllerAdvice批注,然后在其中包含@ExceptionHandler方法。

@ControllerAdvice 
public class ExceptionControllerAdvice {

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM