2015-12-22 62 views
1

我已經發現了什麼是錯的,只是在這裏發佈它,所以使用googling這個異常將返回一些比休眠問題。彈簧安全性自定義權限評估器拋出ClassCastException

我試圖建立的Spring Security 4採用了自定義權限評估,但得到此異常:

HTTP Status 500 - Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation cannot be cast to org.springframework.security.web.FilterInvocation 

那麼我請求http://localhost:8080/my-service/secured/[email protected],這是爲了評估該方法:

@Controller 
public class SecuredServiceController { 

@Autowired 
private SecuredService securedService; 

@RequestMapping(value = "/secured/{name:.+}", method = RequestMethod.GET) 
@PreAuthorize("hasPermission(#name, 'view.%')") 
public ModelAndView stuff(@PathVariable("name") String name) throws ServletException, IOException { 

    ModelAndView model = new ModelAndView(); 
    model.setViewName("hello"); 

    model.addObject("message", securedService.getSecret(name)); 
    return model; 
}} 

但它沒有被調用,在這之前拋出異常。

這裏是我的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" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-4.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 

<security:http auto-config="true" use-expressions="true"> 
    <security:intercept-url pattern="/j_spring_security_check" access="permitAll"/> 
    <security:intercept-url pattern="/free" access="permitAll"/> 
    <security:intercept-url pattern="/test*" access="isAuthenticated()"/> 
    <security:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-url="/logout"/> 
</security:http> 

<security:authentication-manager> 
    <security:authentication-provider ref="myAuthenticationProvider"/> 
</security:authentication-manager> 
<bean id="myAuthenticationProvider" 
     class="com.me.webcommon.spring_auth.MySpringAuthenticationProvider"/> 

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

<bean id="permissionEvaluator" class="com.me.webcommon.spring_auth.MyPermissionEvaluator"/> 

<context:component-scan 
     base-package="com.me.webcommon.spring_auth"/> 
<bean id="expressionHandler" 
     class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"> 
    <property name="permissionEvaluator" ref="permissionEvaluator"/> 
</bean> 

回答

1

在異常仔細地觀察,它說的是一個方法代理不能轉換到過濾器代理。這是因爲,我應該使用的方法表達處理器 org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler
,而是如果org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler
春季創建了一個錯誤的一種代理對象,以從通話中檢索參數並將其傳遞給我的permissionEvaluator調用方法前。

這裏是一個工作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" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-4.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 

<security:http auto-config="true" use-expressions="true"> 
    <security:intercept-url pattern="/j_spring_security_check" access="permitAll"/> 
    <security:intercept-url pattern="/free" access="permitAll"/> 
    <security:intercept-url pattern="/test*" access="isAuthenticated()"/> 
    <security:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-url="/logout"/> 
</security:http> 

<security:authentication-manager> 
    <security:authentication-provider ref="myAuthenticationProvider"/> 
</security:authentication-manager> 
<bean id="myAuthenticationProvider" 
     class="com.me.webcommon.spring_auth.MySpringAuthenticationProvider"/> 

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

<bean id="permissionEvaluator" class="com.me.webcommon.spring_auth.MyPermissionEvaluator"/> 

<context:component-scan 
     base-package="com.me.webcommon.spring_auth"/> 
<!--here, it must be a method expression handler--> 
<bean id="expressionHandler" 
     class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> 
    <property name="permissionEvaluator" ref="permissionEvaluator"/> 
</bean> 

+0

哇...我浪費了幾乎整整一天,在這個確切的問題。我正在使用DefaultWebSecurityExpressionHandler,並在嘗試添加@PreAuthorize註釋時開始獲取代理/篩選器異常。更改爲DefaultMethodSecurityExpressionHandler解決了這個問題。有趣的是我開始使用DefaultMethodSecurityExpressionHandler,但切換到DefaultWebSecurityExpressionHandler來解決一些我不記得了的問題。非常感謝您花時間爲後代發佈此信息。 –