Spring HTTP/HTTPS Channel Security – Spring HTTP/HTTPS通道安全

最后修改: 2016年 5月 8日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

This tutorial shows how to use HTTPS to protect your application’s login page using Spring’s Channel Security feature.

本教程展示了如何使用HTTPS来保护你的应用程序的登录页面,使用Spring的通道安全功能。

Using HTTPS for authentication is crucial to protect the integrity of sensitive data when in transport.

使用HTTPS进行认证对于保护敏感数据在传输中的完整性至关重要。

The article builds on top of the Spring Security Login tutorial by adding an additional layer of security. We highlight the steps needed to secure the authentication data by serving the login page through the encoded HTTPS channel.

本文在Spring安全登录教程的基础上,增加了一个额外的安全层。我们强调了通过编码的HTTPS通道提供登录页面来保护认证数据所需的步骤。

2. Initial Setup Without Channel Security

2.没有通道安全的初始设置

Let’s start out with the security configuration explained in the aforementioned article.

让我们从前述文章中解释的安全配置开始。

The web-app allows users to access:

该网络应用程序允许用户访问。

  1. /anonymous.html without authentication,
  2. /login.html, and
  3. other pages (/homepage.html) after a successful login.

The access is controlled by the following configuration:

访问由以下配置控制。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests() 
      .antMatchers("/anonymous*")
      .anonymous();

    http.authorizeRequests()
      .antMatchers("/login*")
      .permitAll();

    http.authorizeRequests()
      .anyRequest()
      .authenticated();

Or via XML:

或者通过XML。

<http use-expressions="true">
    <intercept-url pattern="/anonymous*" access="isAnonymous()"/>
    <intercept-url pattern="/login*" access="permitAll"/>
    <intercept-url pattern="/**" access="isAuthenticated()"/>
</http>

At this point, the login page is available at:

在这一点上,登录页面可在。

http://localhost:8080/spring-security-login/login.html

Users are able to authenticate themselves through HTTP, however this is insecure as passwords will be sent in plain text.

用户能够通过HTTP进行自我认证,然而这是不安全的,因为密码将以纯文本形式发送。

3. HTTPS Server Configuration

3.HTTPS服务器配置

To only deliver the login page over HTTPS your web-server must be able to serve HTTPS pages. This requires that SSL/TLS support is enabled.

为了只通过HTTPS提供登录页面,你的网络服务器必须能够提供HTTPS页面。这需要启用SSL/TLS支持。

Note that you can either use a valid certificate or, for testing purposes, you can generate your own.

注意,你可以使用一个有效的证书,或者为了测试,你可以生成你自己的证书。

Let’s say we’re using Tomcat and rolling our own certificate. We’ll first need to create a keystore with a self-signed certificate.

比方说,我们使用Tomcat,并滚动使用自己的证书。我们首先需要创建一个带有自签名证书的keystore

Generating the keystore can be done issuing the following command in the terminal:

生成钥匙库可以通过在终端发布以下命令来完成。

keytool -genkey -alias tomcat -keyalg RSA -storepass changeit -keypass changeit -dname 'CN=tomcat'

This will create a private a key and a self-signed certificate in the default keystore for your user profile, in your home folder.

这将在你的主文件夹中为你的用户配置文件的默认密钥库创建一个私人密钥和一个自签名证书。

The next step is to edit conf/server.xml to make it look like this:

下一步是编辑conf/server.xml,使其看起来像这样。

<Connector port="8080" protocol="HTTP/1.1"
   connectionTimeout="20000"
   redirectPort="8443" />

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
   maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
   clientAuth="false" sslProtocol="TLS"
   keystoreFile="${user.home}/.keystore" keystorePass="changeit" />

The second SSL/TLS <Connector> tag is usually commented out in the config file so uncommenting and adding keystore information is all that is needed. Further information is available in Tomcat’s related documentation.

第二个SSL/TLS <Connector>标签通常在配置文件中被注释掉,因此取消注释并添加密钥库信息就可以了。进一步的信息可在Tomcat的相关文档中获得。

With the HTTPS configuration in place, the login page can now be served under the following URL as well:

随着HTTPS配置的到位,登录页面现在也可以在以下URL下提供。

https://localhost:8443/spring-security-login/login.html

Web-servers other than Tomcat would require different but likely similar configuration.

Tomcat以外的Web服务器将需要不同的配置,但可能是类似的配置。

4. Configuring Channel Security

4.配置通道安全

At this point, we are able to serve the login page both under HTTP and HTTPS. This section explains how to mandate the usage of HTTPS.

在这一点上,我们可以在HTTP和HTTPS下提供登录页面。本节解释了如何强制使用HTTPS。

To require HTTPS for the login page modify your security configuration by adding the following:

为了要求登录页面使用HTTPS,请修改您的安全配置,添加以下内容。

http.requiresChannel()
  .antMatchers("/login*").requiresSecure();

Or add the requires-channel=”https” attribute to your XML config:

或者在你的XML配置中添加requires-channel=”https”属性。

<intercept-url pattern="/login*" access="permitAll" requires-channel="https"/>

After this point users could login only via HTTPS. All relative links e.g. a forward to /homepage.html will inherit the protocol of the original request and will be served under HTTPS.

在这一点上,用户只能通过HTTPS登录。所有相对链接,例如转发到/homepage.html,将继承原始请求的协议,并在HTTPS下提供。

When mixing HTTP and HTTPS request inside a single web app, there are additional aspects to be aware of and that require further configuration.

当把HTTP和HTTPS请求混合在一个单一的网络应用程序中时,还有一些需要注意的方面,需要进一步配置。

5. Mixing HTTP and HTTPS

5.混合使用HTTP和HTTPS

From the security perspective, serving everything over HTTPS is good practice and a solid goal to have.

从安全角度来看,通过HTTPS提供一切服务是良好的做法,也是一个坚实的目标。

However, if using HTTPS exclusively is not an option, we can configure Spring to use HTTP by appending the following to the config:

然而,如果完全使用HTTPS不是一种选择,我们可以通过在配置中添加以下内容,将Spring配置为使用HTTP。

http.requiresChannel()
  .anyRequest().requiresInsecure();

Or add requires-channel=”http” attributes to the XML:

或者在XML中添加requires-channel=”http”属性。

<intercept‐url pattern="/**" access="isAuthenticated()" requires‐channel="http"/>

This instructs Spring to use HTTP for all requests that are not explicitely configured to use HTTPS, but at the same time it breaks the original login mechanism. The following sections explain the underlying cause.

这指示Spring对所有没有明确配置为使用HTTPS的请求使用HTTP,但同时也破坏了原有的登录机制。下面几节将解释其根本原因。

5.1. A Custom Login Processing URL Over HTTPS

5.1.通过HTTPS的自定义登录处理URL

The security configuration in the original security tutorial contains the following:

原始安全教程中的安全配置包含以下内容。

<form-login login-processing-url="/perform_login"/>

Without forcing /perform_login to use HTTPS a redirect would happen to the HTTP variant of it, losing the login information sent with the original request.

如果不强迫/perform_login使用HTTPS,就会发生重定向到它的HTTP变体,失去与原始请求一起发送的登录信息

To overcome this we need to configure Spring to use HTTPS for the processing URL:

为了克服这个问题,我们需要配置Spring,使处理URL使用HTTPS。

http.requiresChannel()
  .antMatchers("/login*", "/perform_login");

Notice the extra argument /perform_login passed to the antMatchers method.

注意传递给antMatchers方法的额外参数/perform_login

The equivalent in the XML configuration requires adding a new <intercept-url> element to the config:

在XML配置中的等价物需要在配置中添加一个新的<intercept-url>元素。

<intercept-url pattern="/perform_login" requires-channel="https"/>

If your own application is using the default login-processing-url (which is /login) you don’t need to configure this explicitly as the /login* pattern already covers that.

如果你自己的应用程序使用默认的login-processing-url(也就是/login),你不需要明确配置,因为/login*模式已经涵盖了这一点。

With the configuration in place, users are able to login, but not to access authenticated pages e.g. /homepage.html under the HTTP protocol, because of Spring’s session fixation protection feature.

在配置到位的情况下,用户能够登录,但不能在HTTP协议下访问认证的页面,例如/homepage.html,因为Spring的会话固定保护功能

5.2. Disabling session-fixation-protection

5.2.禁用session-fixation-protection

Session fixation is a problem which can’t be avoided when switching between HTTP and HTTPS.

会话固定是一个在HTTP和HTTPS之间切换时无法避免的问题。

By default Spring creates a new session-id after a successful login. When a user loads the HTTPS login page the user’s session-id cookie will be marked as secure. After logging in, the context will switch to HTTP and the cookie will be lost as HTTP is insecure.

默认情况下,Spring在成功登录后会创建一个新的session-id。当用户加载HTTPS登录页面时,用户的session-id cookie将被标记为安全。登录后,上下文将切换到HTTP,cookie将丢失,因为HTTP是不安全的。

To avoid this setting session-fixation-protection to none is required.

为了避免这种情况s设置session-fixation-protectionnone是必要的

http.sessionManagement()
  .sessionFixation()
  .none();

Or via XML:

或者通过XML。

<session-management session-fixation-protection="none"/>

Disabling session fixation protection might have security implications, therefore you need to weigh the pros and cons if you’re concerned about session fixation based attacks.

禁用会话固定保护可能会产生安全影响,因此,如果你担心基于会话固定的攻击,你需要权衡利弊。

6. Test

6.测试

After applying all these configuration changes accessing /anonymous.html without logging in (using either http:// or https://) will forward you to the page through HTTP.

在应用所有这些配置变化后,在没有登录的情况下访问/anonymous.html(使用http:// 或https://)将通过HTTP将你转到该页面。

Opening other pages directly like /homepage.html should get you forwarded to the login page via HTTPS and after login you will be forwarded back to /homepage.html using HTTP.

直接打开其他页面,如/homepage.html,应该会让你通过HTTPS转发到登录页面,登录后,你将使用HTTP转发回/homepage.html

7. Conclusion

7.结论

In this tutorial we’ve taken a look on how to configure a Spring web-application which communicates through HTTP except for the login mechanism. However new modern web-applications should almost always use HTTPS exclusively as their communication protocol. Lowering security levels or turning off security features (like session-fixation-protection) is never a good idea.

在本教程中,我们了解了如何配置一个Spring Web应用,该应用除登录机制外通过HTTP进行通信。然而,新的现代Web应用几乎总是应该完全使用HTTPS作为其通信协议。降低安全级别或关闭安全功能(如会话固定保护)绝不是一个好主意。

This tutorial is based on the codebase available on GitHub. The channel security configuration can be enabled by listing https as an active Spring profile.

本教程是基于GitHub上提供的代码库编写的。可以通过将https列为活动的Spring配置文件来启用通道安全配置。