All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.nemerosa.ontrack.boot.support.WebSecurityConfig Maven / Gradle / Ivy

There is a newer version: 4.4.5
Show newest version
package net.nemerosa.ontrack.boot.support;

import net.nemerosa.ontrack.model.security.UserSource;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.info.InfoEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.codec.Hex;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;

import java.security.SecureRandom;
import java.util.List;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final APIBasicAuthenticationEntryPoint apiBasicAuthenticationEntryPoint;

    private final AuthenticationManager authenticationManager;

    private final List userSources;

    public WebSecurityConfig(APIBasicAuthenticationEntryPoint apiBasicAuthenticationEntryPoint, AuthenticationManager authenticationManager, List userSources) {
        this.apiBasicAuthenticationEntryPoint = apiBasicAuthenticationEntryPoint;
        this.authenticationManager = authenticationManager;
        this.userSources = userSources;
    }

    /**
     * By default, all queries are accessible anonymously. Security is enforced at service level.
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Gets a secure random key for the remember be token key
        SecureRandom random = new SecureRandom();
        byte[] randomBytes = new byte[64];
        random.nextBytes(randomBytes);
        String rememberBeKey = new String(Hex.encode(randomBytes));
        // @formatter:off
        http.antMatcher("/**")
            // Only BASIC authentication
            .httpBasic()
                .authenticationEntryPoint(apiBasicAuthenticationEntryPoint)
                .realmName("ontrack")
                .and()
            // Logout set-up
            .logout()
                .logoutUrl("/user/logout")
                .logoutSuccessUrl("/user/logged-out")
                .addLogoutHandler(basicRememberMeUserDetailsService())
                .and()
            // FIXME CSRF protection for a stateless API?
            //.csrf().requireCsrfProtectionMatcher(new CSRFRequestMatcher()).and()
            .csrf().disable()
            // Allows all at Web level
            .authorizeRequests()
                .requestMatchers(EndpointRequest.toAnyEndpoint().excluding(
                        InfoEndpoint.class,
                        HealthEndpoint.class
                )).access("hasRole('ADMIN') or @functionBasedSecurity.hasApplicationManagement(authentication)")
                .antMatchers("/**").permitAll()
            // Remember be authentication token
            .and().rememberMe()
                .rememberMeServices(rememberMeServices(rememberBeKey))
                .key(rememberBeKey)
                .tokenValiditySeconds(604800)
            // Cache enabled
            .and().headers().cacheControl().disable()
        ;
        // @formatter:on
    }

    private RememberMeServices rememberMeServices(String rememberBeKey) {
        return new PersistentTokenBasedRememberMeServices(
                rememberBeKey,
                basicRememberMeUserDetailsService(),
                new InMemoryTokenRepositoryImpl()
        );
    }

    @Bean
    public BasicRememberMeUserDetailsService basicRememberMeUserDetailsService() {
        return new BasicRememberMeUserDetailsService(userSources);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.parentAuthenticationManager(authenticationManager);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy