AccessDecisionManager中的HTTP请求缺少标头

时间:2015-08-14 17:38:26

标签: java servlets spring-security

我试图为我的Spring安全保护的servlet实现AccessDecisionManager,并且需要检查"授权"的内容。头。我有以下代码,但标题(我100%确定正在发送)将返回null

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包括我的&#34;授权&#34;标题并具有正确的值,所以我知道标题正在进入我的服务器。但是,TreeMap headers缺少我的授权标头,(我假设)是getHeaders()正在查看的内容。

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

配置为:

<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()函数中的值吗? (或者是否有更好的方法可以根据标题值做出决定?)

1 个答案:

答案 0 :(得分:0)

我无法确定AccessDecisionManager中的问题是什么,或者如何获取对其他请求标头的访问权限。相反,我通过在api路径上禁用Spring Security解决了这个问题:

<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()中的逻辑,这不是理想的,但有效。