2014-04-04 59 views
0

我試圖實現自定義@PreAuthorize方法在我的彈簧(3.2.2)MVC應用程序。但每當我點擊鏈接,這是應該要帶我去哪裏了@PreAuthorize實現它給了我這個錯誤的控制器方法:春自定義授權不能正常工作使用@PreAuthorize

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext 
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948) 
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 


root cause 

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext 
    org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:339) 
    org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:198) 
    org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:60) 
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631) 
    com.nav.qanda.admin.question.controller.AdminQuestionController$$EnhancerByCGLIB$$5bcda356_2.handleRequest(<generated>) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    java.lang.reflect.Method.invoke(Method.java:606) 
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) 
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) 
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) 
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) 
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) 
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 

這是我的應用程序-servlet.xml中

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

    <bean id="expressionHandler" class="com.nav.panda.security.PandaMethodSecurityExpressionHandler" /> 

而這些都是Java文件重寫

public class PandaMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler{ 
     @Override 
     protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, 
       MethodInvocation invocation){ 
     PandaMethodSecurityExpressionRoot root = new PandaMethodSecurityExpressionRoot(authentication); 
     root.setThis(invocation.getThis()); 
     return root; 
     } 



public class PandaMethodSecurityExpressionRoot implements MethodSecurityExpressionOperations { 


    private Object filterObject; 
    private Object returnObject; 
    private Object target; 


    public boolean adminOnly() { 
     System.out.println("Checking admin authority"); 
     return true; 
//  return this.hasAuthority("ADMIN"); 
    } ... other methods 

而且控制器看起來是這樣的:

@RequestMapping(value = "/createPandaPage", method = RequestMethod.GET) 
     @PreAuthorize("adminOnly()") 
     public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) 
       throws ServletException, IOException { 
      return new ModelAndView("admin/createPanda"); 
     } 

的web.xml:

<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

在我的應用程序將填充用戶對象(其中有從數據庫讀取填補了用戶權限)從我的應用程序的登錄。如何通過此用戶對象來檢查權限?而且,我還需要做些什麼來實現這一目標?

回答

3

導致該方法的請求調用需要通過Spring Security的過濾器鏈,否則將沒有安全上下文可用時的權限進行檢查。

沒有看到堆棧跟蹤的其餘部分,我不能說100%,但它看起來就是這裏發生的事情,因爲你看到的異常(如果你搜索錯誤信息,你會發現類似的問題)。

所以,你需要確保你想要安全通過安全過濾器鏈進行處理的申請,以及你的過濾器鏈的配置是否正確(它如果你使用的命名空間應該是自動)。

+0

我已經用完整的堆棧跟蹤更新了這個問題。我如何確保(除了發佈的代碼)請求正在通過Spring Security篩選器?我如何告訴Spring,我的User對象是需要檢查用戶權限的對象。 – happybuddha

+0

我更新了我的web.xml與春季安全過濾器映射(更新問題),現在我的應用程序在所有 – happybuddha

+0

不會加載有一個例子圍繞這表明一個如何使用自定義授權註解連同自定義身份驗證機制,將工作與春季安全? – happybuddha