私は同様の問題に遭遇し、私が来た解決策を共有すると思いました。
まず、SSL証明書の認証がウェブサーバー側で処理されることを理解する必要があります(cfur。durの説明、「clientAuth = want」設定)。 次に、提供された(許可された)証明書を処理し、ユーザーにマップするためにWebアプリケーションを構成する必要があります。
私はあなたと少し違いますが、私は春のブートアプリケーションを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” />
小型コメント:truststoreFileが含まれている一方でいるkeystoreFileは、SSLのために使用される証明書/秘密鍵のペア(のみ)が含まれていクライアントSSL認証用の許可されたCA証明書(クライアント証明書をその信頼ストアに直接追加することもできます)。あなたは春のブートアプリケーションと組み込み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
その後、次のように私のWebアプリに、私は特定の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");
}
}
私はその後、UserDetailsService Bを宣言する必要があります例えば、私のアプリケーションのメインクラス):
@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')")アノテーションを追加できます。次のように
少し物事をまとめると、認証フローは次のようになります。
- ユーザーは、SSL証明書を提供します。
- Tomcatは、その信頼ストアに対して検証します。
- カスタムWebSecurityConfigurerAdapterは、証明書のCNから「username」を取得します。
- アプリケーションは、取得したユーザ名に関連付けられたユーザを認証します。
- メソッドレベルで@PreAuthorize( "hasRole( 'SSL_USER')")でアノテーションを付けた場合、アプリケーションはユーザーに必要な役割があるかどうかをチェックします。
お返事ありがとうございます。提供されたリンクは、Tomcat 7の完全なロックダウンのようですが、これが展開されるサーバーは共有リソースなので、セキュリティ保護されたアイテムとセキュリティで保護されていないアイテムが混在しています。私が本当に探しているのは、Spring Securityとクライアント証明書を使用して単一のWebアプリケーションをロックする方法です。 –
それでは、Spring Bootの組み込みのTomcatコンテナにもっと詳しく調べる必要があります。 –