我写过Spring控制器。这得到了客户的请求。它只是REST风格。
这非常好。但我需要证书身份验证。只有客户端必须能够访问具有密钥的客户端证书的休息服务(spring控制器)(换句话说,客户端应该具有带密钥的密钥库)。
如何将此安全性配置为弹簧?你能给我一个例子或链接吗?
谢谢
答案 0 :(得分:20)
您要找的是Mutual Authentication。
服务器负责发出/请求客户端发送其证书。每个服务器都以不同的方式执行此操作,您必须查找如何配置特定服务器。
对于Spring Security,我建议您查看X.509 Authentication。这种类型的身份验证非常易于使用,并可根据需要进行扩展。
修改强>
所以,这里有几个参考资料,展示了你要问的例子:
http://whiteycode.blogspot.com/2012/04/part-3-x509-authentication-with-spring.html
PDF警告
<击> http://www.promixis.com/pdfs/SpringSecurityAndX509ClientCertificates.pdf 击>
上述pdf文件已无法访问...
此示例非常适合解释如何设置证书和创建自己的个人CA(证书颁发机构)。警告,他们显示制作客户端证书的方式只是一种方式,而不是方式。您的客户端(IE Web浏览器或java httpclient客户端)应确定创建客户端证书的方式。 Java当然喜欢使用它的java密钥库,浏览器倾向于喜欢p12样式的证书。
最后的建议/警告......我不知道你的证书知识水平,但......相互认证完全取决于谁信任谁。委托人有责任说,我需要您使用证书对自己进行身份验证,这里是我信任的证书提供商列表。然后,客户有责任使用由其中一个服务器可信证书提供商签名的证书进行回复。然后,应用程序有责任说,我是否根据证书中的姓名信任此人?如果事情开始出错,请考虑谁是谁,或者不信任谁。
一个很棒的工具是在你的应用程序上使用-Djavax.net.debug = ssl。它将显示整个ssl握手以及请求的内容以及具体的响应。该选项有点冗长,但在需要时很好。
编辑X 2
以下是如何在Tomcat 7上启用相互身份验证。
在您的server.xml配置文件中,您应该看到SSL连接器的以下内容:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="want" sslProtocol="TLS"
keystoreFile="C:\Java\Certs\localhost.jks"
keystorePass="changeit"
URIEncoding="UTF-8" />
需要注意的重要值是clientAuth值。
将clientAuth设置为&#39;想要&#39;告诉客户端从服务器信任的证书列表中发送签名的客户端ssl证书(如果有的话)。如果没有,请继续正常提出您的请求。
将clientAuth设置为&#39; true&#39;告诉客户端他们必须从服务器信任的证书列表中发送签名的客户端ssl证书。如果您没有由服务器信任的证书列表签名的证书,则不允许客户端发出请求。
服务器信任的证书列表来自默认的Java信任库,或者可以使用-Djavax.net.ssl.trustStore="C:\Java\Certs\jssecacerts1"
VM选项进行设置。
通常,如果您信任的特定CA证书不在默认Java信任库中,则会复制默认信任库,新CA证书将导入复制的信任库,然后与上面的VM选项一起使用。
警告强>
非常重要的是不要更改默认的Java信任库。如果这样做,则该计算机上默认的所有Java应用程序都将使用新更新的信任库。并不总是人们想要的,并且可能导致安全风险。
答案 1 :(得分:4)
我创建了一个100%易于理解的示例项目,其中所有需要设置Spring Boot应用程序,其中REST端点由客户端证书保护 - 以及一个带有RestTemplate的Testcase,配置为使用客户端证书与受保护的服务器通信:https://github.com/jonashackt/spring-boot-rest-clientcertificate
它还包含生成.key
,.crt
和.jks
文件所需的所有步骤。如果您不想使用自签名证书,请相应地调整步骤。
RestTemplate的配置如下:
package de.jonashackt.restexamples;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
@Configuration
public class RestClientCertTestConfiguration {
private String allPassword = "allpassword";
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(ResourceUtils.getFile("classpath:keystore.jks"), allPassword.toCharArray(), allPassword.toCharArray())
.loadTrustMaterial(ResourceUtils.getFile("classpath:truststore.jks"), allPassword.toCharArray())
.build();
HttpClient client = HttpClients.custom()
.setSSLContext(sslContext)
.build();
return builder
.requestFactory(new HttpComponentsClientHttpRequestFactory(client))
.build();
}
}
然后您可以像使用Test.class中的@Autowired
注释一样使用它。