2015-08-14 122 views
3

我试图为Spring安全受保护的servlet实现AccessDecisionManager,并且需要检查“授权”标头的内容。我有以下的代码,但头(我敢100%肯定被发送)就要回来nullAccessDecisionManager中的HTTP请求缺少标题

public class MyAccessDecisionManager implements AccessDecisionManager { 
    public void decide(Authentication arg0, Object arg1, Collection<ConfigAttribute> arg2) throws AccessDeniedException, InsufficientAuthenticationException { 
     HttpServletRequest req = ((FilterInvocation) arg1).getHttpRequest(); 
     String authHeader = req.getHeader("Authorization"); //this is null 
     //Do stuff 
    } 
} 

看在调试器req,我可以钻到看起来很有趣的东西请参阅以下结构:

SecurityContextHolderAwareRequestWrapper req 
|-SavedRequestAwareWrapper request 
    |-DefaultSavedRequest savedRequest 
    |-TreeMap headers 
    |-HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper request 
    |-RequestWrapper request 
     |-RequestFacade request 
     |-Request request 
      |-Request coyoteRequest 
      |-MimeHeaders headers 

MimeHeaders headers包括我的“授权”头并且具有正确的价值,所以我知道标题做它到我的服务器。然而,TreeMap headers缺少我的授权标头,并且(我认为)是getHeaders()正在查看的内容。

我试图在客户端添加一个“foo”头来检查问题是否特别与“授权”,但我看到完全相同的行为。我唯一可以访问的标题是“接受编码”,“连接”,“主机”和“用户代理”。

的配置是:

<bean id="myAccessDecisionManager" class="com.example.MyAccessDecisionManager" /> 
<security:http pattern="/api/**" 
    access-decision-manager-ref="myAccessDecisionManager" 
    entry-point-ref="myAccessDeniedHandler"> 
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> 
    <security:anonymous enabled="true"/> 
    <security:access-denied-handler ref="myAccessDeniedHandler"/> 
</security:http> 

谁能解释这是怎么回事或为什么头部丢失?有什么方法可以访问我的decide()函数中的值吗? (或者是否有更好的方法可以根据标题值做出决定?)

+0

你有没有遇到任何错误或只是头部丢失? – Karthik

+0

没有错误,它只是不存在。我编辑了这个问题,但我也尝试添加“foo = bar”来查看它是否具体授权,并看到相同的行为。 – Michelle

回答

0

我无法确定AccessDecisionManager中的问题是什么或者如何访问其他请求标头。相反,我工作围绕该问题由API路径上禁用春季安全:

<security:http pattern="/api/**" security="none"/> 

...和使用Spring MVC的拦截器来代替:

<mvc:interceptors> 
    <mvc:interceptor> 
    <mvc:mapping path="/api/**"/> 
    <bean class="com.example.MyInterceptor"/> 
    </mvc:interceptor> 
</mvc:interceptors> 

我不得不从包括逻辑我的两个AccessDecisionManager和我的AuthenticationEntryPoint在拦截器的preHandle()方法中,这并不理想,但有效。