gpt4 book ai didi

java - 使用 spring boot 实现 2 路 SSL

转载 作者:搜寻专家 更新时间:2023-10-30 19:42:29 26 4
gpt4 key购买 nike

我正在创建一些 Restful Web 服务,并使用 Spring-Boot 创建一个嵌入式 tomcat 容器。

其中一个要求是实现 2 路 SSL。我一直在查看 HttpSecurity 对象,并且可以使用它让它仅通过 SSL channel 运行 Web 服务:-

@Override
protected void configure(HttpSecurity http) throws Exception {

System.out.println("CONFIGURED");

http
// ...
.requiresChannel()
.anyRequest().requiresSecure();
}

我似乎无法找到一种方法,使 Web 服务只能由提供有效客户端证书的应用程序访问。

我只有 SSL 的基本知识,因此即使是正确方向的一般指示也会受到赞赏。

要部署的服务器将混合应用程序 - 这是唯一需要使用 2-way SSL 锁定的应用程序。我真正想要的是一种锁定单个应用程序以仅接受客户端证书的方法。

最佳答案

我遇到了类似的问题,并认为我应该分享我的解决方案。

首先,您需要了解 SSL 证书身份验证将在您的 Web 服务器端处理(参见 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” />

避免混淆的小注释:keystoreFile 包含用于 SSL(仅)的证书/私钥对,而 truststoreFile 包含用于客户端 SSL 身份验证的允许的 CA 证书(请注意,您也可以将客户端证书直接添加到该信任中-商店)。

如果您在 spring boot 应用程序中使用嵌入式 tomcat 容器,您应该能够使用以下属性键/值在应用程序的属性文件中配置这些设置:

server.ssl.key-store=/opt/tomcat/conf/key-stores/ssl-keystore.jks
server.ssl.key-store-password=some-complex-password
server.ssl.trust-store=/opt/tomcat/conf/trust-stores/ssl-truststore.jks
server.ssl.trust-store-password=some-other-complex-password
server.ssl.client-auth=want

然后,在我的网络应用程序上,我声明了一个特定的 SSL 配置,如下所示:

@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");
}

}

然后我需要声明 UserDetailsS​​ervice bean(例如在我的应用程序的主类中):

@Value("${allowed.user}")
private String ALLOWED_USER;

@Bean
public UserDetailsService userDetailsService () {

return new UserDetailsService() {

@Override
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
if (username.equals(ALLOWED_USER)) {
final User user = new User(username, "", AuthorityUtils.createAuthorityList("ROLE_SSL_USER"));
return user;
}
return null;
}
};
}

就是这样!然后,我可以将 @PreAuthorize(“hasRole(‘ROLE_SSL_USER’)”) 注释添加到我想要保护的方法中。

总结一下,身份验证流程如下:

  1. 用户提供SSL证书;
  2. Tomcat 根据其信任库进行验证;
  3. 自定义 WebSecurityConfigurerAdapter 从证书的 CN 中检索“用户名”;
  4. 应用程序验证与检索到的用户名关联的用户;
  5. 在方法级别,如果使用@PreAuthorize("hasRole('SSL_USER')") 注释,应用程序将检查用户是否具有所需的角色。

关于java - 使用 spring boot 实现 2 路 SSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33808603/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com