Java 使用springboot实现双向SSL
我正在创建一些RESTfulWeb服务,并使用SpringBoot创建一个嵌入式tomcat容器 其中一个要求是实现双向SSL。我一直在研究HttpSecurity对象,可以通过以下方法使其仅在SSL通道上运行Web服务:-Java 使用springboot实现双向SSL,java,ssl,spring-security,spring-boot,tomcat8,Java,Ssl,Spring Security,Spring Boot,Tomcat8,我正在创建一些RESTfulWeb服务,并使用SpringBoot创建一个嵌入式tomcat容器 其中一个要求是实现双向SSL。我一直在研究HttpSecurity对象,可以通过以下方法使其仅在SSL通道上运行Web服务:- @Override protected void configure(HttpSecurity http) throws Exception { System.out.println("CONFIGURED"); http // ...
@Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("CONFIGURED");
http
// ...
.requiresChannel()
.anyRequest().requiresSecure();
}
我似乎找不到一种方法,使Web服务仅可供提供有效客户端证书的应用程序访问
我只有SSL的基本知识,所以即使是一个正确方向的一般指针也会很感激
部署到的服务器将混合使用多种应用程序—这是唯一需要使用双向SSL锁定的应用程序。我真正想要的是一种锁定单个应用程序的方法,只接受客户端证书 您可以配置
clientAuth=want
,请参阅:
如果希望SSL堆栈在接受连接之前需要来自客户端的有效证书链,请设置为true
。如果希望SSL堆栈请求客户端证书,请设置为want
,但如果未提供客户端证书,则不会失败。false
值(默认值)不需要证书链,除非客户端请求受使用client-CERT
身份验证的安全约束保护的资源
然后使用以下命令读取客户端证书:
您还可以将SSL与“相互身份验证”一起使用;然后,服务器将从客户端请求有效证书,作为SSL握手的一部分。服务器将通过检查其证书是否由可接受的机构签名来验证客户端。如果提供了有效的证书,则可以通过应用程序中的ServletAPI获取该证书。Spring Security X.509模块使用过滤器提取证书。它将证书映射到应用程序用户,并加载该用户的一组授权权限,以便与标准的Spring安全基础架构一起使用
及
clientAuth
也可以设置为want
,如果您仍然希望SSL连接成功,即使客户端没有提供证书。除非您使用非X.509身份验证机制,例如表单身份验证,否则不提供证书的客户端将无法访问由Spring Security保护的任何对象
我遇到了一个类似的问题,我想我会分享我带来的解决方案 首先,您需要了解SSL证书身份验证将在web服务器端处理(cfr.dur的解释,带有“clientAuth=want”设置)。 然后,必须配置您的web应用程序,以便处理提供的(和允许的)证书、将其映射到用户等 我与您之间的一个细微差别是,我正在将我的spring boot应用程序打包到WAR归档中,然后将其部署到现有的Tomcat应用程序服务器上 我的Tomcat的server.xml配置文件定义了一个HTTPS连接器,如下所示:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="/opt/tomcat/conf/key-stores/ssl-keystore.jks"
keystorePass=“some-complex-password“
clientAuth="want" sslProtocol="TLS"
truststoreFile="/opt/tomcat/conf/trust-stores/ssl-truststore.jks"
truststorePass=“some-other-complex-password” />
@Configuration
@EnableWebSecurity
//In order to use @PreAuthorise() annotations later on...
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SSLAuthConfiguration extends WebSecurityConfigurerAdapter {
@Value("${allowed.user}")
private String ALLOWED_USER;
@Value("${server.ssl.client.regex}")
private String CN_REGEX;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure (final HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/url-path-to-protect").authenticated() //Specify the URL path(s) requiring authentication...
.and()
.x509() //... and that x509 authentication is enabled
.subjectPrincipalRegex(CN_REGEX)
.userDetailsService(userDetailsService);
}
@Autowired
//Simplified case, where the application has only one user...
public void configureGlobal (final AuthenticationManagerBuilder auth) throws Exception {
//... whose username is defined in the application's properties.
auth
.inMemoryAuthentication()
.withUser(ALLOWED_USER).password("").roles("SSL_USER");
}
}
然后,在我的web应用程序上,我声明了一个特定的SSL配置,如下所示:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="/opt/tomcat/conf/key-stores/ssl-keystore.jks"
keystorePass=“some-complex-password“
clientAuth="want" sslProtocol="TLS"
truststoreFile="/opt/tomcat/conf/trust-stores/ssl-truststore.jks"
truststorePass=“some-other-complex-password” />
@Configuration
@EnableWebSecurity
//In order to use @PreAuthorise() annotations later on...
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SSLAuthConfiguration extends WebSecurityConfigurerAdapter {
@Value("${allowed.user}")
private String ALLOWED_USER;
@Value("${server.ssl.client.regex}")
private String CN_REGEX;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure (final HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/url-path-to-protect").authenticated() //Specify the URL path(s) requiring authentication...
.and()
.x509() //... and that x509 authentication is enabled
.subjectPrincipalRegex(CN_REGEX)
.userDetailsService(userDetailsService);
}
@Autowired
//Simplified case, where the application has only one user...
public void configureGlobal (final AuthenticationManagerBuilder auth) throws Exception {
//... whose username is defined in the application's properties.
auth
.inMemoryAuthentication()
.withUser(ALLOWED_USER).password("").roles("SSL_USER");
}
}
然后我需要声明UserDetailsService bean(例如,在我的应用程序的主类中):
就这样!然后,我可以将@PreAuthorize(“hasRole('ROLE\u SSL\u USER'))注释添加到我想要保护的方法中
总而言之,身份验证流程如下所示:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="/opt/tomcat/conf/key-stores/ssl-keystore.jks"
keystorePass=“some-complex-password“
clientAuth="want" sslProtocol="TLS"
truststoreFile="/opt/tomcat/conf/trust-stores/ssl-truststore.jks"
truststorePass=“some-other-complex-password” />
@Configuration
@EnableWebSecurity
//In order to use @PreAuthorise() annotations later on...
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SSLAuthConfiguration extends WebSecurityConfigurerAdapter {
@Value("${allowed.user}")
private String ALLOWED_USER;
@Value("${server.ssl.client.regex}")
private String CN_REGEX;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure (final HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/url-path-to-protect").authenticated() //Specify the URL path(s) requiring authentication...
.and()
.x509() //... and that x509 authentication is enabled
.subjectPrincipalRegex(CN_REGEX)
.userDetailsService(userDetailsService);
}
@Autowired
//Simplified case, where the application has only one user...
public void configureGlobal (final AuthenticationManagerBuilder auth) throws Exception {
//... whose username is defined in the application's properties.
auth
.inMemoryAuthentication()
.withUser(ALLOWED_USER).password("").roles("SSL_USER");
}
}
谢谢你的回复。提供的链接似乎是为了完全锁定tomcat 7,但是将在其上部署的服务器是一个共享资源,因此将在其上混合使用安全和非安全项目。我真正想要的是一种使用Spring Security和客户端证书锁定单个web应用程序的方法。因此,我可能需要进一步了解Spring Boot中嵌入的tomcat容器。对于我来说,使用Spring Boot 2.3.4可以节省我很多时间