Цепная аутентификация в Spring Security

1

Могу ли я подключить несколько экземпляров AuthenticationEntryPoint в Spring Security 3.2.4?

Я пытаюсь создать следующий сценарий:

  • Определенный URL-адрес защищен Spring Security
  • Используемый AuthenticationEntryPoint - LoginUrlAuthenticationEntryPoint
  • Интерфейс администратора может запускать службы по этому URL-адресу
  • Администратор может выбрать для обеспечения этих услуг с помощью CLIENT-CERT

Когда пользователь пытается получить доступ к защищенному URL-адресу:

  1. Если путь был защищен с помощью CLIENT-CERT аутентификация завершается с ошибкой, если только они не предоставили действительный сертификат, соответствующий пользователю в UserService. Стандартная x509 подлинности Spring x509.
  2. Как только пользователь выполнил аутентификацию в соответствии с первой точкой или если URL-адрес не защищен с помощью CLIENT-CERT, они FORM на страницу проверки подлинности на основе FORM.
  3. После успешной аутентификации с именем пользователя и паролем они направляются на целевую страницу.

Я работаю на Tomcat 7.0.54 с clientAuth="want". Это отлично работает в "простой" настройке Spring Security, то есть с одним WebSecurityConfigurerAdapter установленным в x509() и другим набором для formLogin() в соответствии с этим примером

Итак, я хочу, чтобы поток процессов выглядел следующим образом:

Изображение 174551

У меня был некоторый успех при динамическом изменении используемого метода проверки подлинности с помощью DelegatingAuthenticationEntryPoint но:

  • При использовании AntPathRequestMatcher для сопоставления, скажем, /form/** для LoginUrlAuthenticationEntryPoint сервлет аутентификации (/j_spring_security_check) дает ошибку HTTP404.
  • При использовании AntPathRequestMatcher для отображения, скажем, /cert/** на Http403ForbiddenEntryPoint данные пользователя не извлекаются из представленного клиентского сертификата, поэтому это дает ошибку HTTP403.

Я также не вижу, как заставить пользователя дважды пройти проверку подлинности.

Я использую java-config, а не XML.

Мой код:

У меня есть DelegatingAuthenticationEntryPoint:

@Bean
public AuthenticationEntryPoint delegatingEntryPoint() {
    final LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map = Maps.newLinkedHashMap();
    map.put(new AntPathRequestMatcher("/basic/**"), new BasicAuthenticationEntryPoint());
    map.put(new AntPathRequestMatcher("/cert/**"), new Http403ForbiddenEntryPoint());

    final DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint(map);
    entryPoint.setDefaultEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));

    return entryPoint;
}

И моя configure

@Override
protected void configure(final HttpSecurity http) throws Exception {
    defaultConfig(http)
            .headers()
            .contentTypeOptions()
            .xssProtection()
            .cacheControl()
            .httpStrictTransportSecurity()
            .addHeaderWriter(new XFrameOptionsHeaderWriter(SAMEORIGIN))
            .and()
            .authorizeRequests()
            .accessDecisionManager(decisionManager())
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic()
            .authenticationEntryPoint(delegatingEntryPoint())
            .and()
            .sessionManagement()
            .maximumSessions(1)
            .sessionRegistry(sessionRegistry())
            .maxSessionsPreventsLogin(true);
}

Где decisionManager() возвращает экземпляр UnanimousBased. sessionRegistry() возвращает экземпляр SessionRegistryImpl. Оба метода - @Bean.

Я добавляю пользовательский UserDetailsService используя:

@Autowired
public void configureAuthManager(
        final AuthenticationManagerBuilder authBuilder,
        final InMemoryUserDetailsService authService) throws Exception {
    authBuilder.userDetailsService(authService);
}

И у меня есть собственный FilterInvocationSecurityMetadataSource сопоставленный с использованием BeanPostProcessor как в этом примере.

Теги:
spring-security
spring
authentication
spring-java-config

1 ответ

1
Лучший ответ

Цепочка нескольких точек входа не будет работать.

Ваш лучший вариант здесь может состоять в том, чтобы просто настроить процесс регистрации форм, чтобы проверить наличие сертификата (до аутентификации пользователя). Это, вероятно, упростит конфигурацию в целом. Это было бы точно так же, как обычная форма входа в систему.

Работа, проделанная фильтром X509, весьма минимальна. Например, вы можете переопределить метод attemptAuthentication, вызвать super.attemptAuthentication() а затем проверить, соответствует ли информация о сертификате полученной информации о проверке подлинности пользователя.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню