使用Spring Security'hasPermission()'返回有关未授权REST服务请求的JSON [英] Return JSON on unauthorized REST service request using Spring Security 'hasPermission()'
问题描述
我正在使用Spring安全性实现方法级别限制/授权(在 REST服务上)。
我使用了spring表达式语言并实现了自定义Expression Evaluator。
I am implementing method level restriction/authorization (on REST services) using Spring security.
I have used the spring expression language and implemented custom Expression Evaluator.
这对我来说很好。但是,如果未经授权的用户尝试访问该服务,则它将使用登录页面进行响应。由于我的应用程序仅基于REST ,我想只返回所有请求的JSON数据。
It is working fine for me. However, if an unauthorized user tries to access the service, it is responding with a login page. Since my application is REST based only, I want to return only JSON data for all the requests.
如何让它返回JSON而不是登录页面?(例如: {status:Denied}
)
How do I make it return JSON instead of the login page?(eg: {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。
What is happening is an AccessDeniedException
is being thrown, so you want to configure your system to intercept that exception and instead return JSON.
您可以设置<$控制器中的$ $ $ $ $>> @Exc但是,您可能希望在所有控制器中执行相同的操作,因此如果您使用的是Spring 3.2,则可以在单独的advice类中使用 @ControllerAdvice
注释,然后在那里包含 @ExceptionHandler
方法。
You can set up an @ExceptionHandler
method within your controller which catches the AccessDeniedException
. However, you probably want to do the same thing in all your controllers, so if you are using Spring 3.2, you can use @ControllerAdvice
annotation on a separate 'advice' class and then include the @ExceptionHandler
method in there.
@ControllerAdvice
public class ExceptionControllerAdvice {
@ExceptionHandler(AccessDeniedException.class)
@ResponseBody
public String exception(AccessDeniedException e) {
return "{\"status\":\"access denied\"}";
}
}
这篇关于使用Spring Security'hasPermission()'返回有关未授权REST服务请求的JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!