如何使用Tomcat + Spring Security为静态内容强制执行HTTPS

时间:2015-05-25 10:14:55

标签: spring tomcat https

我有一个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配置不正确,但我无法弄明白。

1 个答案:

答案 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。