我试图为我的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()
函数中的值吗? (或者是否有更好的方法可以根据标题值做出决定?)
答案 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()
中的逻辑,这不是理想的,但有效。