0

I am trying to secure my Spring Boot 3 (SNAPSHOT) application with SAML SSO to access the "index.html" (Angular frontend) and to secure the API with JWT.

I have both SSO and JWT working to secure the whole application (both access to application and to the API) but I'm not able to configure the SecurityConfig in a way that every user that hits the "/" path (https://localhost:9091/) gets redirected to the IDP and after authenticating granting full access to the application (access to the static resources - compiled angular files) and at the same time that every user that hits "/api/**" path is required to have a valid JWT token, without the requirement of authenticating against the IDP.

Below is my code, pretty mixed up. Also attached is my project on GitHub.



@Configuration
public class SecurityConfiguration {
    
    @Bean
    SecurityFilterChain configure(HttpSecurity http) throws Exception {

        OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
        authenticationProvider.setResponseAuthenticationConverter(groupsConverter());




            http.authorizeHttpRequests(authorize -> authorize
           .requestMatchers("/").authenticated())
            .saml2Login(saml2 -> saml2
                .authenticationManager(new ProviderManager(authenticationProvider)))
            .saml2Logout(withDefaults());

            http.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                            .authorizeHttpRequests(authorize -> authorize
                                    .requestMatchers("/saml2/service-provider-metadata/**").permitAll()
                                    .requestMatchers("/api/auth/**").permitAll()
                                    .requestMatchers("/api/test/**").permitAll()
                                    .requestMatchers("/").permitAll()
                                    .requestMatchers(h2ConsolePath + "/**").permitAll()
                                    .anyRequest().authenticated());


        // fix H2 database console: Refused to display ' in a frame because it set 'X-Frame-Options' to 'deny'
        http.headers().frameOptions().sameOrigin();

        http.authenticationProvider(authenticationProvider());

        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }


    private Converter<OpenSaml4AuthenticationProvider.ResponseToken, Saml2Authentication> groupsConverter() {

        Converter<ResponseToken, Saml2Authentication> delegate =
            OpenSaml4AuthenticationProvider.createDefaultResponseAuthenticationConverter();

        return (responseToken) -> {
            Saml2Authentication authentication = delegate.convert(responseToken);
            Saml2AuthenticatedPrincipal principal = (Saml2AuthenticatedPrincipal) authentication.getPrincipal();
            List<String> groups = principal.getAttribute("groups");
            //log.info()
            Set<GrantedAuthority> authorities = new HashSet<>();
            if (groups != null) {
                groups.stream().map(SimpleGrantedAuthority::new).forEach(authorities::add);
            } else {
                authorities.addAll(authentication.getAuthorities());
            }
            return new Saml2Authentication(principal, authentication.getSaml2Response(), authorities);
        };
    }

    @Value("${spring.h2.console.path}")
    private String h2ConsolePath;

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    @Autowired
    private AuthEntryPointJwt unauthorizedHandler;

    @Bean
    public AuthTokenFilter authenticationJwtTokenFilter() {
        return new AuthTokenFilter();
    }

}

0 Answers0