java - AccessDecisionManager 中的 HTTP 请求缺少 header

标签 java servlets spring-security

我正在尝试为受 Spring 安全保护的 servlet 实现 AccessDecisionManager,并且需要检查“Authorization” header 的内容。我有以下代码,但 header (我 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 header 包含我的“Authorization” header 并具有正确的值,因此我知道该 header 正在发送到我的服务器。但是,TreeMap headers 缺少我的授权 header ,并且(我假设)是 getHeaders() 正在查看的内容。

我尝试在客户端添加“foo” header 来检查问题是否专门与“授权”有关,但我看到了完全相同的行为。我有权访问的唯一 header 是“accept-encoding”、“connection”、“host”和“user-agent”。

配置为:

<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>

任何人都可以解释发生了什么事或为什么 header 丢失?有什么方法可以访问我的 decide() 函数中的值吗? (或者是否有更好的方法来根据 header 值做出决策?)

最佳答案

我无法确定 AccessDecisionManager 中的问题是什么或如何获取对其他请求 header 的访问权限。相反,我通过在 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>

我必须将 AccessDecisionManagerAuthenticationEntryPoint 的逻辑包含在拦截器的 preHandle() 方法中,这并不理想,但有效。

关于java - AccessDecisionManager 中的 HTTP 请求缺少 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32015800/

相关文章:

java - 我需要在图片的范围内创建一个可点击的图像。然后我需要图片在文件夹中的图片之间切换

servlets - 使用特殊的自动启动 servlet 在启动时进行初始化并共享应用程序数据

spring-security - 关键 CloudFoundry : Enforcing HTTPS (SSL)

grails - 带有Spring Security Core的Grails仅允许所有者在GSP中进行更新

redirect - Spring Security-Grails 3.2.2-ERR_TOO_MANY_REDIRECTS

java - 使用 JCanvas 时获取 KeyPressed

java - Mockito anyBoolean() 返回时匹配器异常

java - 更改 File 对象中最深目录的名称

java - 使用来自 JavaBean 的数据填充 JSP 页面中的复选框

java - 连接 Tomcat 6 和 MySQL 5(+ Plandora 项目管理软件)