Автор оригинала: Denis Szczukocki.
1. Обзор
В этом учебнике мы предоставим обзор весенней безопасности Kerberos.
Мы напишем клиента Kerberos на Java, который разрешает себе доступ к нашему сервису Kerberized. И мы забудем наш собственный встроенный центр распределения ключей для выполнения полной, полной проверки подлинности Kerberos. Все это, без какой-либо внешней инфраструктуры требуется благодаря Весенняя безопасность Керберос .
2. Керберос и его преимущества
Kerberos — это протокол проверки подлинности сети, созданный Mit в 1980-х годах, специально полезный для централизации аутентификации в сети.
В 1987 году Массачусетский технологический институт выпустил его открытый исходный сообщества, и он все еще находится в стадии активного развития. В 2005 году он был канонизирован как стандарт IETF в соответствии с RFC 4120 .
Как правило, Керберос используется в корпоративной среде . Там он обеспечивает охрану окружающей среды таким образом, что пользователь не должен проверку подлинности каждой службы отдельно . Это архитектурное решение известно как Единый знак на .
Проще говоря, Kerberos является билетной системой. Пользователь аутентификации один раз и получает билет-дарующий билет (TGT). После этого, инфраструктура сети обменивает то TGT для билетов обслуживания. Эти сервисные билеты позволяют пользователю взаимодействовать с инфраструктурными службами, до тех пор, пока TGT действителен, что, как правило, в течение нескольких часов.
Таким образом, это здорово, что пользователь только знаки в одно время. Но есть и польза для безопасности: в такой обстановке пароль пользователя никогда не отправляется по сети . Вместо этого, Kerberos использует его в качестве фактора для создания другого секретного ключа, который будет использоваться для шифрования сообщений и расшифровки.
Другим преимуществом является то, мы можем управлять пользователями из центрального места, сказать один, который опирается на LDAP. Поэтому, если мы отключим учетную запись в нашей централизованной базе данных для данного пользователя, то мы отзовем его доступ в нашу инфраструктуру. Таким образом, администраторам не нужно отменять доступ отдельно в каждой службе.
Введение в SPNEGO/Kerberos Аутентификация весной обеспечивает углубленный обзор технологии.
3. Керберизованная окружающая среда
Итак, давайте создадим среду для проверки подлинности с помощью протокола Kerberos. Среда будет состоять из трех отдельных приложений, которые будут работать одновременно.
Во-первых, У нас будет центр распределения ключей который будет выступать в качестве точки проверки подлинности. Далее мы напишем приложение «Клиент и услуга», которое мы настройим для использования протокола Kerberos.
Теперь для работы Kerberos требуется немного установки и конфигурации. Тем не менее, мы будем использовать Весенняя безопасность Керберос , так что мы будем запускать центр распределения ключей программно, во встроенном режиме. Кроме того, МиниКдк приведенное ниже полезно в случае интеграционного тестирования с помощью инфраструктуры Kerberized.
3.1. Запуск центра распределения ключей
Во-первых, мы запустим наш центр распределения ключей, который будет выдавать TGTs для нас:
String[] config = MiniKdcConfigBuilder.builder() .workDir(prepareWorkDir()) .principals("client/localhost", "HTTP/localhost") .confDir("minikdc-krb5.conf") .keytabName("example.keytab") .build(); MiniKdc.main(config);
В принципе, мы дали МиниКдк набор принципов и файл конфигурации; кроме того, мы сказали МиниКдк как назвать keytab он генерирует.
МиниКдк будет генерировать 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. Заявка клиента
Нашим клиентом будет приложение Spring Boot, используя РестТемплет для звонков на внешний API REST.
Но, мы собираемся использовать КерберосРестТемплет вместо . Он будет нуждаться в 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); } }
И это все! КерберосРестТемплет ведет переговоры с клиентом по протоколу Kerberos для нас.
Итак, давайте создадим быстрый класс, который будет запрашивать некоторые данные из Керберизированной службы, размещенные в конечной точке app.access-url :
@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, настраивая его с соответствующими Керберос конкретных бобов.
Кроме того, обратите внимание, что служба будет иметь свой основной и использовать keytab, тоже:
@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; } }
Интро статья содержит все реализации выше, так что мы опуская полные методы здесь для краткости.
Обратите внимание, что мы настроили Spring Security для Проверка подлинности SPNEGO . Таким образом, мы сможем проверить подлинность с помощью протокола HTTP, хотя мы также можем достичь Проверка подлинности SPNEGO с помощью основных Java- .
4. Тестирование
Теперь мы забудем интеграционный тест, чтобы показать, что наш клиент успешно извлекает данные с внешнего сервера по протоколу Kerberos . Чтобы выработать этот тест, нам нужно, чтобы наша инфраструктура была запущена, так МиниКдк и наше приложение обслуживания оба должны быть запущены.
В принципе, мы будем использовать наши ОбразецКлиент из приложения Клиента, чтобы сделать запрос в нашу заявку на обслуживание. Давайте проверить его:
@Autowired private SampleClient sampleClient; @Test public void givenKerberizedRestTemplate_whenServiceCall_thenSuccess() { assertEquals("data from kerberized server", sampleClient.getData()); }
Обратите внимание, что мы также можем доказать, что КерберизРестТемплет важно, нажав на службу без него:
@Test public void givenRestTemplate_whenServiceCall_thenFail() { sampleClient.setRestTemplate(new RestTemplate()); assertThrows(RestClientException.class, sampleClient::getData); }
В качестве примечания, есть шанс наш второй тест может повторно использовать билет, уже хранящийся в кэш учетных данных . Это произойдет из-за автоматических переговоров SPNEGO, используемых в HttpUrlConnection .
В результате данные могут фактически вернуться, что приведет к аннулированию нашего теста. В зависимости от наших потребностей, мы можем отключить использование кэша билетов через системный http.use.global.creds-false.
5. Заключение
В этом учебнике мы исследовали Kerberos для централизованного управления пользователями и как Spring Security поддерживает протокол Kerberos и механизм проверки подлинности SPNEGO.
Мы использовали МиниКдк встать встроенный KDC, а также создал очень простой Kerberized клиента и сервера. Эта настройка была удобна для исследования и особенно удобна, когда мы создали интеграционный тест для тестирования вещей.
Мы только что поцарапали поверхность. Чтобы погрузиться глубже, проверить Керберос вики-страница или его RFC . Кроме того, официальная страница документации будет полезно. Помимо этого, чтобы увидеть, как вещи могут быть сделаны в основной Java, следуя учебнику Oracle показывает его в деталях.
Как обычно, код можно найти на нашем GitHub страница.