как интегрировать приложение Spring Boot как с SAML, так и с токеном JWT: множественный WebSecurityConfigurerAdapter

#java #spring-boot #jwt #saml #okta

#java #spring-boot #jwt #saml #okta

Вопрос:

Я пытаюсь использовать как токен JWT, так и SAML в моем приложении spring boot. Мое приложение создает токен JWT, используя имя пользователя, возвращенное из OKTA.

Поток:

  1. При нажатии https://localhost:8088/my_app / API-приложение должно перенаправить на страницу входа в OKTA, а затем получить имя пользователя в ответ.
  2. На основе имени пользователя создайте токен JWT.
  3. Используйте токен JWT для аутентификации остальных API.

Я могу перейти из приложения на страницу входа в OKTA, аутентифицировать пользователя и получить имя пользователя. Затем после этого шага я пытаюсь создать токен JWT, используя это имя пользователя.

Проблема, с которой я сталкиваюсь, заключается в том, что, поскольку у меня есть два WebSecurityConfigurerAdapter, один для перенаправления SAML, а другой для JWT, я не могу ограничить API-интерфейсы наличием токена JWT. Мое приложение не проверяет все API на наличие токена JWT.

Когда я отключаю SAML, JWT работает, если я отключаю JWT, SAML работает нормально. Теперь может кто-нибудь, пожалуйста, скажите мне, как я могу настроить свое приложение на использование конфигураций веб-безопасности SAML и JWT?

 @Confguration
@EnableWebSecurity
public class SecurityConfig {
    @Order(1)
    @Configuration
    public static class SAMLConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private SAMLUserDetailsServiceImpl samlUserDetailsServiceImpl;
        @Value("${security.saml2.metadata-url}")
        String metadataUrl;
        @Value("${server.ssl.key-alias}")
        String keyAlias;
        @Value("${server.ssl.key-store-password}")
        String password;
        @Value("${server.port}")
        String port;
        @Value("${server.ssl.key-store}")
        String keyStoreFilePath;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.requestMatchers()
                    .antMatchers("/saml*").and()
                    .apply(saml())
                    .serviceProvider()
                    .keyStore()
                    .storeFilePath(this.keyStoreFilePath)
                    .password(this.password)
                    .keyname(this.keyAlias)
                    .keyPassword(this.password)
                    .and()
                    .protocol("https")
                    .hostname(String.format("%s:%s", "localhost", this.port))
                    .basePath("/my_app")
                    .and()
                    .identityProvider()
                    .metadataFilePath(this.metadataUrl);
        }

    }


    @Order(2)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
        @Autowired
        private UserDetailsService jwtUserDetailsService;
        @Autowired
        private JwtRequestFilter jwtRequestFilter;

        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            //encrypts user passweod so its not visible to outside world
            auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
        }

        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }

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


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


            httpSecurity.requestMatchers()
                    .antMatchers("/user/hello").and().authorizeRequests().anyRequest().authenticated().and().
                            exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
            httpSecurity.cors();
            httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

        }

        @Bean
        CorsConfigurationSource corsConfigurationSource() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
            return source;
        }


    }
}