401 SPNEGO SSO с клиентом Linux

Мне не удается настроить виртуальную машину Ubuntu для единого входа в мое веб-приложение Spring Security под Spnego. Я сделал что-то не так или я что-то упустил?

Я уже добрался до SSO на виртуальной машине Windows 7, поэтому я считаю, что это специфично для Linux.

Моя конфигурация подробно описана ниже.


Инфраструктура

У меня есть четыре машины, которые работают на двух разных аппаратных средствах:

  1. WIN-SRV2008.company.local: VM KDC под управлением Windows Server 2008 (аппаратное обеспечение A)
  2. TOMCAT.company.local: запуск веб-приложения Tomcat 7 (аппаратное обеспечение А)
  3. W7-CLIENT.company.local: клиент виртуальной машины Windows 7, на котором работает система единого входа (аппаратное обеспечение B)
  4. U-CLIENT.company.local: клиент VM Ubuntu 17.10.1, у которого система единого входа не работает (аппаратное обеспечение B)

SPN

Мои SPN, krb5.ini и login.conf были основаны на описание этой темы.


Спнего

В основном я следил за Spring Security Kerberos — справочник Документация, за исключением удаления формы входа в систему, что привело к:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${kerberos.service-principal}")
    private String servicePrincipal;

    @Value("${kerberos.keytab-location}")
    private String keytabLocation;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        AffirmativeBased affirmativeBased = new AffirmativeBased(Arrays.asList(new RoleVoter(),new WebExpressionVoter()));
        http
            .authorizeRequests().accessDecisionManager(affirmativeBased)
            .anyRequest().authenticated()
            .and()
        .httpBasic()
            .authenticationEntryPoint(entryPoint())
            .and()
        .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .and()
        .addFilterBefore(
                    spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
                    BasicAuthenticationFilter.class)
        .sessionManagement()
        .invalidSessionUrl("/login")
        .maximumSessions(1)
        .maxSessionsPreventsLogin(true)
        .sessionRegistry(sessionRegistry());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .authenticationProvider(kerberosAuthenticationProvider())
            .authenticationProvider(kerberosServiceAuthenticationProvider());
    }

    @Bean
    public SpnegoEntryPoint entryPoint() {
        return new SpnegoEntryPoint();
    }

    @Bean
    public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
        LoginKerberosAuthentication provider = new LoginKerberosAuthentication();
        SunJaasKerberosClient client = new SunJaasKerberosClient();
        client.setDebug(true);
        provider.setKerberosClient(client);
        provider.setUserDetailsService(usuarioDetailsService());
        return provider;
    }

    @Bean
    public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
        AuthenticationManager authenticationManager) {
        SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
        filter.setAuthenticationManager(authenticationManager);
        return filter;
    }

    @Bean
    public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
        KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
        provider.setTicketValidator(sunJaasKerberosTicketValidator());
        provider.setUserDetailsService(usuarioDetailsService());
        return provider;
    }

    @Bean
    public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
        SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
        ticketValidator.setServicePrincipal(servicePrincipal);
        ticketValidator.setKeyTabLocation(new FileSystemResource(keytabLocation));
        ticketValidator.setDebug(true);
        return ticketValidator;
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public UsuarioDetailsService usuarioDetailsService() {
        return new UsuarioDetailsService();
    }

Клиент Ubuntu

Чтобы присоединиться к домену, я выполнил следующие шаги:

sudo apt-get install realmd krb5-user software-properties-common python-software-properties packagekit

sudo realm join COMPANY.local -U '[email protected]' -v

Пока я не сгенерировал билет kerberos с помощью:

kinit [email protected]

Я действительно проверил кеш с помощью klist, который вывел:

Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: [email protected]

Valid starting        Expires                Service principal
30/10/2018 17:25:47   31/10/2018 03:25:47    krbtgt/[email protected]
            renew until 31/10/2018 17:25:43

И, наконец, я успешно прошел аутентификацию, используя:

sudo su [email protected]

Система единого входа – проблема

Когда я пытаюсь получить доступ к домашней странице моего приложения с помощью Firefox (с конфигурацией надежных сайтов), как и с клиентом Windows 7, я получаю только заголовок 401 Negotiate, и токен ответа не отправляется. Это означает, что когда я ввожу фактический URL-адрес конструктора SpnegoEntryPoint, меня перенаправляют на этот запасной вариант.


заранее спасибо


person unelunatriste    schedule 30.10.2018    source источник
comment
Что ты делаешь с этим su <kerberos principal>?!?!? Кэш тикетов Kerberos доступен только пользователю Linux, выполнившему команду kinit. Если вы su после этого, вы переключаетесь на другой кеш (предположительно пустой)   -  person Samson Scharfrichter    schedule 31.10.2018
comment
@SamsonScharfrichter Вы были правы, и это сработало!! Большое спасибо. Я слепо следовал руководству по настройке Linux AD и подумал, что su подходит для тестирования билета.   -  person unelunatriste    schedule 31.10.2018


Ответы (1)


Благодаря комментарию Самсона я смог заставить его работать.

Я действительно переключился на пустой кеш, выполнив sudo su [email protected], что заставило вход в мое приложение ответить 401.

person unelunatriste    schedule 03.07.2019