1. 개요
이 예제에서는 Spring Security Kerberos에 대한 개요를 제공합니다.
Kerberized 서비스에 액세스 할 수있는 권한을 부여하는 Kerberos 클라이언트를 Java로 작성할 것입니다. 또한 자체 내장 된 키 배포 센터를 실행하여 완전한 종단 간 Kerberos 인증을 수행 할 것입니다. Spring Security Kerberos 덕분에 외부 인프라가 필요하지 않습니다 .
2. Kerberos와 그 이점
Kerberos는 MIT가 1980 년대에 만든 네트워크 인증 프로토콜로, 특히 네트워크에서 인증을 중앙 집중화하는 데 유용합니다.
1987 년에 MIT는 그것을 오픈 소스 커뮤니티에 공개했으며 아직 활발하게 개발 중입니다. 2005 년에는 RFC 4120에 따라 IETF 표준으로 정식화되었습니다 .
일반적으로 Kerberos는 기업 환경에서 사용됩니다 . 여기에서는 사용자가 각 서비스에 대해 개별적으로 인증 할 필요가 없도록 환경을 보호합니다 . 이 아키텍처 솔루션을 Single Sign-on이라고 합니다.
간단히 말해 Kerberos는 티켓팅 시스템입니다. 사용자 는 한 번 인증 하고 TGT ( Ticket-Granting Ticket )를받습니다. 그런 다음 네트워크 인프라는 해당 TGT를 서비스 티켓으로 교환합니다. 이러한 서비스 티켓을 통해 사용자는 TGT가 유효하고 일반적으로 몇 시간 동안 인프라 서비스와 상호 작용할 수 있습니다.
따라서 사용자가 한 번만 로그인하는 것이 좋습니다. 그러나 Security상의 이점도 있습니다. 이러한 환경에서는 사용자의 암호가 네트워크를 통해 전송되지 않습니다 . 대신 Kerberos는 메시지 암호화 및 암호 해독에 사용될 또 다른 비밀 키를 생성하는 요인으로 사용합니다.
또 다른 이점은 LDAP가 지원 하는 중앙 위치에서 사용자를 관리 할 수 있다는 것 입니다. 따라서 특정 사용자에 대해 중앙 데이터베이스에서 계정을 비활성화하면 인프라에서 그의 액세스가 취소됩니다. 따라서 관리자는 각 서비스에서 개별적으로 액세스를 취소 할 필요가 없습니다.
Spring의 SPNEGO / Kerberos 인증 소개 는 기술에 대한 심층적 인 개요를 제공합니다.
3. Kerberos화된 환경
따라서 Kerberos 프로토콜로 인증하기위한 환경을 만들어 보겠습니다. 환경은 동시에 실행되는 세 개의 개별 응용 프로그램으로 구성됩니다.
먼저 인증 지점 역할을 할 키 배포 센터 가 있습니다. 다음으로 Kerberos 프로토콜을 사용하도록 구성 할 클라이언트 및 서비스 응용 프로그램을 작성합니다.
이제 Kerberos를 실행하려면 약간의 설치 및 구성이 필요합니다. 그러나 Spring Security Kerberos를 활용 하므로 임베디드 모드에서 프로그래밍 방식으로 키 배포 센터를 실행할 것입니다. 또한 아래 표시된 MiniKdc 는 Kerberized 인프라와의 통합 테스트에 유용합니다.
3.1. 키 배포 센터 실행
먼저 키 배포 센터를 시작하여 TGT를 발급합니다.
String[] config = MiniKdcConfigBuilder.builder()
.workDir(prepareWorkDir())
.principals("client/localhost", "HTTP/localhost")
.confDir("minikdc-krb5.conf")
.keytabName("example.keytab")
.build();
MiniKdc.main(config);
기본적으로 MiniKdc 에 일련의 주체와 구성 파일을 제공했습니다. 또한 MiniKdc 가 생성 하는 키탭 을 호출하도록 지시 했습니다.
MiniKdc 는 클라이언트 및 서비스 애플리케이션에 제공 할 krb5.conf 파일을 생성합니다 . 이 파일에는 KDC를 찾을 수있는 정보 (주어진 영역의 호스트 및 포트)가 포함되어 있습니다.
MiniKdc.main 은 KDC를 시작하고 다음과 같은 내용을 출력해야합니다.
Standalone MiniKdc Running
---------------------------------------------------
Realm : EXAMPLE.COM
Running at : localhost:localhost
krb5conf : .\spring-security-sso\spring-security-sso-kerberos\krb-test-workdir\krb5.conf
created keytab : .\spring-security-sso\spring-security-sso-kerberos\krb-test-workdir\example.keytab
with principals : [client/localhost, HTTP/localhost]
3.2. 클라이언트 애플리케이션
우리의 클라이언트는 RestTemplate 을 사용하여 REST API를 외부로 호출 하는 Spring Boot 애플리케이션이 될 것 입니다.
그러나 대신 KerberosRestTemplate 을 사용할 것 입니다. keytab과 클라이언트 주체가 필요합니다.
@Configuration
public class KerberosConfig {
@Value("${app.user-principal:client/localhost}")
private String principal;
@Value("${app.keytab-location}")
private String keytabLocation;
@Bean
public RestTemplate restTemplate() {
return new KerberosRestTemplate(keytabLocation, principal);
}
}
그리고 그게 다야! KerberosRestTemplate 은 Kerberos 프로토콜의 클라이언트 측을 협상합니다.
따라서 엔드 포인트 app.access-url 에서 호스팅되는 Kerberized 서비스의 일부 데이터를 쿼리하는 빠른 클래스를 만들어 보겠습니다 .
@Service
class SampleClient {
@Value("${app.access-url}")
private String endpoint;
private RestTemplate restTemplate;
// constructor, getter, setter
String getData() {
return restTemplate.getForObject(endpoint, String.class);
}
}
이제이 클래스가 호출 할 무언가를 갖도록 서비스 애플리케이션을 만들어 보겠습니다!
3.3. 서비스 신청
Spring Security를 사용하여 적절한 Kerberos 특정 bean으로 구성합니다.
또한 서비스에는 주체가 있으며 키 탭도 사용됩니다.
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${app.service-principal:HTTP/localhost}")
private String servicePrincipal;
@Value("${app.keytab-location}")
private String keytabLocation;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(spnegoEntryPoint())
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout().permitAll()
.and()
.addFilterBefore(spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
BasicAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(kerberosAuthenticationProvider())
.authenticationProvider(kerberosServiceAuthenticationProvider());
}
@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
// provider configuration
return provider;
}
@Bean
public SpnegoEntryPoint spnegoEntryPoint() {
return new SpnegoEntryPoint("/login");
}
@Bean
public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
AuthenticationManager authenticationManager) {
SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
// filter configuration
return filter;
}
@Bean
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
// auth provider configuration
return provider;
}
@Bean
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
// validator configuration
return ticketValidator;
}
}
소개 기사는 우리가 간결 여기에 전체 방법을 생략하고, 그래서 모든 구현 위에 포함되어 있습니다.
SPNEGO 인증을 위해 Spring Security를 구성했습니다 . 이렇게하면 HTTP 프로토콜을 통해 인증 할 수 있지만 코어 Java를 사용하여 SPNEGO 인증을 얻을 수도 있습니다 .
4. 테스트
이제 통합 테스트를 실행하여 클라이언트가 Kerberos 프로토콜을 통해 외부 서버에서 데이터를 성공적으로 검색했음을 보여줍니다 . 이 테스트를 실행하려면 인프라를 실행해야하므로 MiniKdc 와 서비스 응용 프로그램을 모두 시작해야합니다.
기본적으로 클라이언트 애플리케이션 의 SampleClient 를 사용하여 서비스 애플리케이션에 요청합니다. 테스트 해 보겠습니다.
@Autowired
private SampleClient sampleClient;
@Test
public void givenKerberizedRestTemplate_whenServiceCall_thenSuccess() {
assertEquals("data from kerberized server", sampleClient.getData());
}
KerberizedRestTemplate 이없는 서비스를 사용하여 중요 하다는 것을 증명할 수도 있습니다.
@Test
public void givenRestTemplate_whenServiceCall_thenFail() {
sampleClient.setRestTemplate(new RestTemplate());
assertThrows(RestClientException.class, sampleClient::getData);
}
참고로 두 번째 테스트에서 자격 증명 캐시 에 이미 저장된 티켓을 재사용 할 수 있는 가능성 이 있습니다 . 이것은 HttpUrlConnection 에서 사용되는 자동 SPNEGO 협상으로 인해 발생합니다 .
결과적으로 데이터가 실제로 반환되어 테스트가 무효화 될 수 있습니다. 필요에 따라 시스템 속성 http.use.global.creds = false를 통해 티켓 캐시 사용을 비활성화 할 수 있습니다 .
5. 결론
이 예제에서는 중앙 집중식 사용자 관리를위한 Kerberos 와 Spring Security가 Kerberos 프로토콜 및 SPNEGO 인증 메커니즘을 지원하는 방법 을 살펴 보았습니다 .
MiniKdc 를 사용 하여 임베디드 KDC를 세우고 매우 간단한 Kerberized 클라이언트와 서버를 만들었습니다. 이 설정은 탐색에 편리했으며 특히 테스트를위한 통합 테스트를 만들 때 유용했습니다.
이제 우리는 표면을 긁었습니다. 더 자세히 알아 보려면 Kerberos 위키 페이지 또는 해당 RFC를 확인하세요 . 또한 공식 문서 페이지 가 유용 할 것입니다. 그 외에도 코어 자바에서 작업을 수행 할 수있는 방법을 알아보기 위해 다음 Oracle 사용방법(예제) 에서 자세히 보여줍니다.
평소처럼 코드는 GitHub 페이지 에서 찾을 수 있습니다 .