Рубрики
Без рубрики

Весенняя интеграция безопасности Kerberos с MiniKdc

Краткий и практический обзор интеграции Spring Security с Kerberos и MiniKdc

Автор оригинала: 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 страница.