스프링 부트를 사용하여 양방향 SSL 구현
저는 편안한 웹 서비스를 만들고 있으며 Spring-Boot을 사용하여 내장된 Tomcat 컨테이너를 만들고 있습니다.
요구 사항 중 하나는 양방향 SSL을 구현해야 한다는 것입니다.HttpSecurity 개체를 보고 있는데 다음을 사용하여 SSL 채널을 통해서만 웹 서비스를 실행할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("CONFIGURED");
http
// ...
.requiresChannel()
.anyRequest().requiresSecure();
}
제가 찾을 수 없는 것처럼 보이는 것은 웹 서비스를 유효한 클라이언트 인증서를 제공하는 응용 프로그램에서만 액세스할 수 있도록 만드는 방법입니다.
저는 SSL에 대한 기본적인 지식만 가지고 있기 때문에 일반적인 포인터라도 올바른 방향으로 해주시면 감사하겠습니다.
이 서버가 배포되는 서버에는 여러 응용프로그램이 있습니다. 이 응용프로그램만 양방향 SSL로 잠급니다.제가 정말로 찾고 있는 것은 클라이언트 인증서만 허용하도록 단일 응용프로그램을 잠그는 방법입니다.
저는 비슷한 문제에 부딪혔고, 제가 가지고 온 해결책을 공유해야겠다고 생각했습니다.
먼저, SSL 인증서 인증은 웹 서버 측에서 처리된다는 것을 이해해야 합니다(cfr.dur의 설명, "클라이언트"와 함께).Auth=adm" 설정).그런 다음 제공된(그리고 허용된) 인증서를 처리하고 사용자에게 매핑하기 위해 웹 앱을 구성해야 합니다.
제가 여러분과 약간 다른 점은 봄 부팅 애플리케이션을 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 인증서가 포함되어 있습니다(클라이언트 인증서를 해당 신뢰 저장소에 직접 추가할 수도 있음).
스프링 부팅 응용 프로그램과 함께 내장된 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");
}
}
그런 다음 UserDetailsService been(예: 내 애플리케이션의 기본 클래스)을 선언해야 합니다.
@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에서 "사용자 이름"을 검색합니다.
- 응용 프로그램은 검색된 사용자 이름과 연결된 사용자를 인증합니다.
- 메서드 수준에서 @PreAuthorize("hasRole('SSL_USER'))로 주석을 달면 응용 프로그램은 사용자에게 필요한 역할이 있는지 확인합니다.
를 구성할 수 .clientAuth=want
Apache Tomcat 8 구성 참조:
다음으로 설정
true
연결을 수락하기 전에 SSL 스택에 클라이언트의 유효한 인증서 체인이 필요하도록 하려면 이 옵션을 선택합니다.다음으로 설정want
SSL 스택이 클라이언트 인증서를 요청하지만 인증서가 제공되지 않는 경우 실패하지 않도록 하려면 이 옵션을 선택합니다.false
value 조건에 의해 한 하지 않습니다.CLIENT-CERT
인증
그런 다음 Spring Security - X.509 Authentication으로 클라이언트 인증서를 읽습니다.
또한 "상호 인증확인"과 함께 SSL을 사용할 수 있습니다. 그러면 서버는 SSL 핸드셰이크의 일부로 클라이언트에 유효한 인증서를 요청합니다.서버는 인증서가 허용 가능한 기관에 의해 서명되었는지 확인하여 클라이언트를 인증합니다.유효한 인증서가 제공된 경우, 애플리케이션의 서블릿 API를 통해 인증서를 얻을 수 있습니다.Spring Security X.509 모듈은 필터를 사용하여 인증서를 추출합니다.인증서를 응용프로그램 사용자에게 매핑하고 표준 Spring Security 인프라와 함께 사용할 수 있도록 해당 사용자의 부여된 권한 집합을 로드합니다.
그리고.
clientAuth
으로 설정할 수도 있습니다.want
클라이언트가 인증서를 제공하지 않더라도 SSL 연결이 성공하기를 원하는 경우.인증서를 제공하지 않는 클라이언트는 양식 인증과 같은 비 X.509 인증 메커니즘을 사용하지 않는 한 Spring Security에서 보호하는 개체에 액세스할 수 없습니다.
언급URL : https://stackoverflow.com/questions/33808603/implementing-2-way-ssl-using-spring-boot
'source' 카테고리의 다른 글
임시 테이블을 명시적으로 삭제하거나 SQL Server에서 처리하도록 허용 (0) | 2023.07.06 |
---|---|
기존 노드에 대한 스웨거 문서 생성JS 서버 (0) | 2023.07.06 |
존재함/존재하지 않음: 'select 1' vs 'select field' (0) | 2023.07.06 |
Oracle 함수가 있는 문자열에서 숫자 추출 (0) | 2023.07.06 |
Windows 서비스로서의 스프링 부트 JAR (0) | 2023.07.06 |