Spring security SAML OpenAM

#java #spring-security #single-sign-on #openam

#java #spring-безопасность #единый вход #openam

Вопрос:

Я пытаюсь разработать веб-приложение, используя интерфейс с angular2 и серверную часть REST с spring boot.

Мне нужно управлять 3 типами аутентификации: — базовое сопоставление логина и пароля с базой данных — аутентификация ldap — аутентификация единого входа

Когда пользователь проходит проверку подлинности, серверная часть генерирует JWT и отправляет его во внешний интерфейс. Все запросы должны содержать jwt в заголовке для связи с REST.

На данный момент моя конфигурация веб-безопасности :

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

    private static final String LDAP_AUTHENTIFICATION = "ldap";
    private static final String SSO_AUTHENTIFICATION = "sso";

    @Autowired
    private DataBaseAuthentificationProvider authProvider;

    @Value("${ldap.provider.url}")
    private String ldapProviderUrl;

    @Value("${ldap.user.dn.patterns}")
    private String userDnPatterns;

    @Value("${authentification.type}")
    private String authentificationType;

    public WebSecurityConfiguration() {
        /*
         * Ignores the default configuration, useless in our case (session
         * management, etc..)
         */
        super(true);
    }

    /**
     * Configure AuthenticationManagerBuilder to use the specified
     * DetailsService.
     * 
     * @param auth
     *            the {@link AuthenticationManagerBuilder} to use
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        if (StringUtils.equals(authentificationType, LDAP_AUTHENTIFICATION)) { // LDAP
            auth.ldapAuthentication().userDnPatterns(userDnPatterns).contextSource().url(ldapProviderUrl);
        } else if (StringUtils.equals(authentificationType, SSO_AUTHENTIFICATION)) { // SSO

        } else { // Database
            auth.authenticationProvider(authProvider);
        }

    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        /*
         * Overloaded to expose Authenticationmanager's bean created by
         * configure(AuthenticationManagerBuilder). This bean is used by the
         * AuthenticationController.
         */
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {

        /*
         * the secret key used to signe the JWT token is known exclusively by
         * the server. With Nimbus JOSE implementation, it must be at least 256
         * characters longs.
         */
        String secret = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("secret.key"),
                Charset.defaultCharset());

        httpSecurity.addFilterAfter(jwtTokenAuthenticationFilter("/**", secret), ExceptionTranslationFilter.class)
                .addFilterBefore(new SimpleCORSFilter(), CorsFilter.class)
                /*
                 * Exception management is handled by the
                 * authenticationEntryPoint (for exceptions related to
                 * authentications) and by the AccessDeniedHandler (for
                 * exceptions related to access rights)
                 */
                .exceptionHandling().authenticationEntryPoint(new SecurityAuthenticationEntryPoint())
                .accessDeniedHandler(new RestAccessDeniedHandler()).and()
                /*
                 * anonymous() consider no authentication as being anonymous
                 * instead of null in the security context.
                 */
                .anonymous().and()
                /* No Http session is used to get the security context */
                .sessionManagement().sessionCreationPolicy(STATELESS).and().authorizeRequests()
                /*
                 * All access to the authentication service are permitted
                 * without authentication (actually as anonymous)
                 */
                .antMatchers("/auth/**").permitAll()
                /*
                 * All the other requests need an authentication. Role access is
                 * done on Methods using annotations like @PreAuthorize
                 */
                .anyRequest().authenticated().and().addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class).csrf()
                .csrfTokenRepository(csrfTokenRepository()).disable();
    }

    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN"); // this is the name angular
        // uses by default.
        return repository;
    }

    private JwtTokenAuthenticationFilter jwtTokenAuthenticationFilter(String path, String secret) {
        return new JwtTokenAuthenticationFilter(path, secret);
    }
  

Критической точкой является SSO :

Поведение, которое я хотел бы, заключается в следующем :

Клиент запрашивает защищенный ресурс REST:

  • если пользователь уже зарегистрирован OpenAM => вернуть запрошенный ресурс
  • если пользователь еще не зарегистрирован => пользователь перенаправляется на OpenAM и предоставляет свои учетные данные => пользователь может получить доступ к ресурсу

Сначала я установил OpenAM на виртуальной машине, создал провайдеров SAMLv2 и получил свой idp.xml .

Я пытаюсь использовать https://github.com/vdenotaris/spring-boot-security-saml-sample чтобы добавить аутентификацию единого входа, но это не удается.

Кто-нибудь может дать мне инструкции по интеграции этого в мою конфигурацию веб-безопасности?

Спасибо!

Комментарии:

1. В чем ваша ошибка? Недавно я установил сервер OpenAM и испытал некоторое разочарование, но, наконец, смог заставить его работать (с OpenSAML)

2. Нет ошибки Я не понимаю, как интегрировать opnsaml в мою конфигурацию аутентификации, чтобы иметь 3 типа аутентификации.

3. Привет, вам удалось решить вашу проблему? Можете ли вы опубликовать несколько указателей?

Ответ №1:

Я бы придерживался использования JWT, а не SAML, это усложняет работу без каких-либо преимуществ, есть множество примеров того, как защитить службу REST с помощью JWT, а openam поддерживает OIDC, который предоставляет токены JWT.

Некоторые полезные ссылки:

Интеграция безопасности OpenAM spring

Springboot OIDC OpenAM