为什么没有 jsessionid 的资源会被拒绝访问?
我构建了一个在我自己的本地环境中运行良好的应用程序。但是,当我部署到使用 Siteminder 进行身份验证的开发环境时,所有图像和 css 文件都出现“访问被拒绝”的情况。我注意到身份验证后,url 中附加了一个 jsessionid,因此测试了手动复制+粘贴该 jsessionid 到图像 url 的情况。现在图像显示!
任何人都知道可能出了什么问题吗?为什么 jsessionid 对于访问图像和 CSS 很重要?
如果有帮助的话,我很乐意发布任何代码示例...
**编辑
我已经打开了一些额外的日志记录,我看到了问题所在,但实际上不知道如何解决它。
19:40:27,236 INFO [STDOUT] 2010-12-17 19:40:27,236 [http-0.0.0.0-30080-1] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException: SM_USER header not found in request.
at org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter.getPreAuthenticatedPrincipal(RequestHeaderAuthenticationFilter.java:43)
at org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doAuthenticate(AbstractPreAuthenticatedProcessingFilter.java:98)
at org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doFilter(AbstractPreAuthenticatedProcessingFilter.java:86)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
我的 Spring 安全设置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="securityMetadataSource">
<security:filter-security-metadata-source>
<security:intercept-url pattern="/"
access="ROLE_VIEW_WELCOME" />
<security:intercept-url pattern="/cfs"
access="ROLE_VIEW_WELCOME" />
<security:intercept-url pattern="/app"
access="ROLE_VIEW_WELCOME" />
<security:intercept-url pattern="/welcome/**"
access="ROLE_VIEW_WELCOME" />
<security:intercept-url pattern="/styles/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/scripts/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/images/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/ruleManagement/**"
access="ROLE_VIEW_RULE_MANAGEMENT" />
<security:intercept-url pattern="/vendorManagement/**"
access="ROLE_VENDOR_MANAGEMENT" />
<security:intercept-url pattern="/userManagement/**"
access="ROLE_USER_MANAGEMENT" />
<security:intercept-url pattern="/titleManagement/**"
access="ROLE_TITLE_MANAGEMENT" />
<security:intercept-url pattern="/typeManagement/**"
access="ROLE_TYPE_MANAGEMENT" />
<security:intercept-url pattern="/seriesManagement/**"
access="ROLE_SERIES_MANAGEMENT" />
<security:intercept-url pattern="/sequenceManagement/**"
access="ROLE_SEQUENCE_MANAGEMENT" />
<security:intercept-url pattern="/roleManagement/**"
access="ROLE_GROUP_MANAGEMENT" />
<security:intercept-url pattern="/reports/**"
access="ROLE_REPORTS" />
<security:intercept-url pattern="/reportsNew/**"
access="ROLE_REPORTS" />
<security:intercept-url pattern="/fingerprint/**"
access="ROLE_FINGERPRINT" />
<security:intercept-url pattern="/**"
access="ROLE_VIEW_OTHER" />
</security:filter-security-metadata-source>
</property>
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="preauthenticationProcessingFilterEntryPoint" />
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<security:authentication-manager alias="authenticationManagerParent" />
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager"
parent="authenticationManagerParent">
<property name="providers">
<list>
<ref local="preauthAuthProvider" />
</list>
</property>
</bean>
<bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false" />
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
<bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl" />
<bean id="defaultConcurrentSessionController"
class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
<property name="sessionRegistry" ref="sessionRegistry" />
<property name="exceptionIfMaximumExceeded" value="true" />
</bean>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**"
filters="securityContextPersistenceFilter, exceptionTranslationFilter, siteminderFilter, filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name='securityContextRepository'>
<bean
class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<property name='allowSessionCreation' value='true' />
</bean>
</property>
</bean>
<bean id="siteminderFilter"
class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="SM_USER" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="continueFilterChainOnUnsuccessfulAuthentication"
value="false" />
</bean>
<bean id="mockSiteMinderFilter" class="com.disney.cfs.util.SiteMinderMockFilter"/>
<bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="userDetailsService"/>
</bean>
<bean id="userDetailsService" class="com.disney.cfs.util.UserDetailsServiceUtil"/>
<bean id="preauthenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp" />
</bean>
</beans>
I've built an app that works great on my own local environment. But when I deploy to our development environment which uses Siteminder for authentication, I get an "access denied" for all images and css files. I noticed after authentication there'a a jsessionid appended to the url, so tested manually copying+pasting that jsessionid to the image url. The image now shows!
Anyone have any idea what could be going wrong? How come the jsessionid is important for access to images and css?
I'd be glad to post any code examples if that helps...
**Edit
I've turned on some extra logging and I see where the issue is, but not really how to solve it.
19:40:27,236 INFO [STDOUT] 2010-12-17 19:40:27,236 [http-0.0.0.0-30080-1] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException: SM_USER header not found in request.
at org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter.getPreAuthenticatedPrincipal(RequestHeaderAuthenticationFilter.java:43)
at org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doAuthenticate(AbstractPreAuthenticatedProcessingFilter.java:98)
at org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doFilter(AbstractPreAuthenticatedProcessingFilter.java:86)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
My Spring security settings:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="securityMetadataSource">
<security:filter-security-metadata-source>
<security:intercept-url pattern="/"
access="ROLE_VIEW_WELCOME" />
<security:intercept-url pattern="/cfs"
access="ROLE_VIEW_WELCOME" />
<security:intercept-url pattern="/app"
access="ROLE_VIEW_WELCOME" />
<security:intercept-url pattern="/welcome/**"
access="ROLE_VIEW_WELCOME" />
<security:intercept-url pattern="/styles/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/scripts/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/images/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/ruleManagement/**"
access="ROLE_VIEW_RULE_MANAGEMENT" />
<security:intercept-url pattern="/vendorManagement/**"
access="ROLE_VENDOR_MANAGEMENT" />
<security:intercept-url pattern="/userManagement/**"
access="ROLE_USER_MANAGEMENT" />
<security:intercept-url pattern="/titleManagement/**"
access="ROLE_TITLE_MANAGEMENT" />
<security:intercept-url pattern="/typeManagement/**"
access="ROLE_TYPE_MANAGEMENT" />
<security:intercept-url pattern="/seriesManagement/**"
access="ROLE_SERIES_MANAGEMENT" />
<security:intercept-url pattern="/sequenceManagement/**"
access="ROLE_SEQUENCE_MANAGEMENT" />
<security:intercept-url pattern="/roleManagement/**"
access="ROLE_GROUP_MANAGEMENT" />
<security:intercept-url pattern="/reports/**"
access="ROLE_REPORTS" />
<security:intercept-url pattern="/reportsNew/**"
access="ROLE_REPORTS" />
<security:intercept-url pattern="/fingerprint/**"
access="ROLE_FINGERPRINT" />
<security:intercept-url pattern="/**"
access="ROLE_VIEW_OTHER" />
</security:filter-security-metadata-source>
</property>
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="preauthenticationProcessingFilterEntryPoint" />
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<security:authentication-manager alias="authenticationManagerParent" />
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager"
parent="authenticationManagerParent">
<property name="providers">
<list>
<ref local="preauthAuthProvider" />
</list>
</property>
</bean>
<bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false" />
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
<bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl" />
<bean id="defaultConcurrentSessionController"
class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
<property name="sessionRegistry" ref="sessionRegistry" />
<property name="exceptionIfMaximumExceeded" value="true" />
</bean>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**"
filters="securityContextPersistenceFilter, exceptionTranslationFilter, siteminderFilter, filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name='securityContextRepository'>
<bean
class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<property name='allowSessionCreation' value='true' />
</bean>
</property>
</bean>
<bean id="siteminderFilter"
class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="SM_USER" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="continueFilterChainOnUnsuccessfulAuthentication"
value="false" />
</bean>
<bean id="mockSiteMinderFilter" class="com.disney.cfs.util.SiteMinderMockFilter"/>
<bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="userDetailsService"/>
</bean>
<bean id="userDetailsService" class="com.disney.cfs.util.UserDetailsServiceUtil"/>
<bean id="preauthenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp" />
</bean>
</beans>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
检查您的浏览器设置。可能是你的cookie被禁用了。在这种情况下,识别会话的唯一方法是通过 URL 参数传递它。
另一种可能性是配置您的身份验证包 (Siteminder)。我个人不知道,但我猜想可能需要通过参数传递会话 ID,然后将其与从 cookie 中获取的值进行比较。这是一种制作非常安全的应用程序的方法,这让黑客的日子变得非常艰难。因此,对您来说更好的解决方案可能是将 jsessionid 附加到每个 url。如果您使用自定义标签库,您可以轻松做到这一点。在这种情况下,您可以实现自己的标记“a”,将 jsessionid 附加到 href 的每个值。
Check your browser settings. Probably your cookies are disabled. In this case the only way to identify session is passing it through the URL parameter.
Other possibility is a configuration of your authentication package (Siteminder). I personally do not know it but I guess that probably it requires passing the session ID through parameter and then compares it with the value it fetches from cookies. This is a way to make very secure applications that make hacker's life very hard. So, probably the better solution for you is to append the jsessionid to each url. You can do it easily if you are using custom tag libraries. In this case you can implement your own tag "a" that appends jsessionid to each value of href.