Spring security SAML OpenAM
Asked Answered
C

1

7

I'm trying to develop a web application using a frontend with angular2 and a REST backend with spring boot.

I need to manage with 3 types of authentification : - basic login/password matching againts database - ldap authentification - sso authentification

When user is authenticated, a JWT is generated by backend and send to frontend. All requests must contain jwt in the header to communicate with REST.

At this time my websecurity config is :

@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);
    }

Critical point is SSO :

The behaviour I would like is the following :

Client asks for a protected REST resource:

  • if user is already logged by OpenAM => return asked resource
  • if user is not already logged => user is redirected to OpenAM and gives its credentials => user can access resource

First, I intalled OpenAM on a virtual machine, created a SAMLv2 Providers and get my idp.xml.

I try to use https://github.com/vdenotaris/spring-boot-security-saml-sample to add sso authentification but it fails.

Does anyone can give to me the steps in order to integrate this in my websecurity config ?

Thanks!

Cassation answered 6/10, 2016 at 14:32 Comment(3)
What is your error? I recently put up an OpenAM server and went through some frustration, but finally managed to get it to work (with OpenSAML)Baseboard
No error I don't understand how to integrate opnsaml in my auth configuration in order to have 3 authentifications types.Cassation
Hi, did you manage to solve your problem? Can you post some pointers?Maniple
A
0

I would stick to using JWT, and not SAML, its adds complexity for no benefits, there are plenty of examples how to protect a REST service using JWT, and openam supports OIDC which provides JWT tokens.

Some usefull links:

OpenAM spring security integration

Springboot OIDC OpenAM

Airless answered 8/1, 2021 at 14:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.