我有一个Spring 4.1.1,Spring安全3.2.5,在Tomcat 8服务器上运行的JSF 2.2.3 Web应用程序。
我需要所有内容,包括所有静态内容,只能通过HTTPS访问。
我设法为动态内容执行此操作,但静态内容仍可通过HTTP直接访问,例如使用网址http://localhost:8080/static/images/image.png
。我还需要将其重定向到HTTPS。
server.xml中
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<Connector port="8443" SSLEnabled="true"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLSv1"
keystoreFile="C:/Java/jdk1.8.0_40/bin/keystore.jks"
keystorePass="xxx" />
的web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>Automatic HTTPS Redirect</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted Methods</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>TRACE</http-method>
<http-method>OPTIONS</http-method>
</web-resource-collection>
<auth-constraint />
</security-constraint>
spring_security.xml (删节版)
<?xml version="1.0" encoding="UTF-8"?>
<beans >
<!-- Configure Spring Security -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<security:password-encoder ref="passwordEncoderBean">
<security:salt-source ref="saltSource"/>
</security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource" >
<property name="userPropertyToUse" value="salt"/>
</bean>
<bean id="passwordEncoderBean" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<constructor-arg value="256" />
</bean>
<bean id="userDetailsService" class="com.pippo.security.UserDetailsImpl"/>
<bean id="authenticationProcessingFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureHandler" ref="failureHandler" />
<property name="authenticationSuccessHandler" ref="successHandler" />
<property name="filterProcessesUrl" value="/spring/loginProcess"/>
</bean>
<bean id="successHandler" class="com.pippo.security.pippoAuthenticationSuccessHandler" >
<property name="defaultTargetUrl" value="/spring/flows/client_main_flow" />
<property name="roleManager" ref="roleManager" />
<property name="geoIPManager" ref="geoIPManager" />
<constructor-arg>
<map value-type="java.lang.String" key-type="java.lang.String">
<entry key="ROLE_ADMIN" value="/spring/flows/admin_main_flow"/>
<entry key="ROLE_ANON" value="/spring/flows/public"/>
<entry key="DENIED" value="/spring/flows/access_denied"/>
</map>
</constructor-arg>
</bean>
<bean id="failureHandler" class="com.pippo.security.CustomAuthenticationFailureHandler" >
<property name="defaultFailureUrl" value="/pippo" />
</bean>
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/spring/flows/public"/>
</bean>
<security:http entry-point-ref="authenticationEntryPoint" pattern="/spring/**">
<security:anonymous />
<security:http-basic />
<security:custom-filter position="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter" />
<security:logout logout-url="/spring/logout" success-handler-ref="logoutController"/>
<security:intercept-url pattern="/spring/login" access="ROLE_ANON,ROLE_USER,ROLE_ADMIN" />
<security:intercept-url pattern="/spring/logoutSuccess" access="ROLE_ANON,ROLE_USER" />
<security:intercept-url pattern="/spring/intro" access="ROLE_ANON,ROLE_USER" />
<security:intercept-url pattern="/spring/flows/admin_main_flow/**" access="ROLE_ADMIN" />
</security:http>
<security:http security="none" pattern="/javax.faces.resource/**" />
<security:http security="none" pattern="/ajax/**" />
<security:http security="none" pattern="/static/**" />
<security:http security="none" pattern="/resources/**" />
<security:http security="none" pattern="/spring/flows/public/**" />
<bean id="logoutController" class="com.pippo.security.LogoutHandlerImpl"/>
<bean id="eventDispatcher" class="com.pippo.listener.EventDispatcher"/>
</beans>
请注意,如果我加载任何包含对静态内容(如CSS或JavaScript文件或图像)的安全引用的页面,则可以通过HTTPS正确检索所有静态内容。问题是针对静态内容的直接网址,如上面的(http://localhost:8080/static/images/image.png
)应该重定向到HTTPS但不是。
我还尝试添加拦截网址代替security none
,但它也不起作用:
<security:http pattern="/static/**" entry-point-ref="authenticationEntryPoint" use-expressions="true">
<security:intercept-url pattern="/static/**" requires-channel="https" access="permitAll"/>
</security:http>
我猜Tomcat配置不正确,但我无法弄明白。
答案 0 :(得分:2)
<security:http security="none" pattern="url-pattern" />
表示Spring Security不会拦截模式匹配url-pattern
之后的任何请求。因此,您的静态资源URL不属于Spring Security框架的范围。
为了实现所需的行为,配置应更改为:
<security:intercept-url access="permitAll" pattern="url-pattern" requires-channel="https"/>
此配置表示应允许所有用户访问与模式url-pattern
匹配的网址,并且应对这些网址实施HTTPS。