botorabi/HomieCenter

View on GitHub
src/main/java/net/vrfun/homiecenter/security/WebSecurityConfig.java

Summary

Maintainability
A
0 mins
Test Coverage
B
80%
/*
 * Copyright (c) 2018 - 2021 by Botorabi. All rights reserved.
 * https://github.com/botorabi/HomieCenter
 *
 * License: MIT License (MIT), read the LICENSE text in
 *          main directory for more details.
 */
package net.vrfun.homiecenter.security;


import net.vrfun.homiecenter.reverseproxy.CameraProxyRoutes;
import org.slf4j.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.*;
import org.springframework.http.*;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.header.XFrameOptionsServerHttpHeadersWriter;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
import org.springframework.web.reactive.function.server.*;
import reactor.core.publisher.Mono;

import java.io.File;

/**
 * Web security configuration
 *
 * @author          boto
 * Creation Date    23th April 2018
*/
@EnableWebFluxSecurity
public class WebSecurityConfig {

    private final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);

    /**
     * Is development mode enabled?
     */
    @Value("${enable-dev-mode: false}")
    private boolean developmentModeEnabled;

    /**
     * Pass -Duse-filesystem-resources=true on java command line in order to use filesystem web resources.
     */
    @Value("${use-filesystem-resources: false}")
    private boolean useFileSystemResources;


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

    /**
     * Reactive web seems to need the static path explicitly.
     * In addition we provide a filesystem resource folder during development, it eases the work with Angular.
     */
    @Bean
    public RouterFunction<ServerResponse> staticResourceRouter(){
        if (developmentModeEnabled && useFileSystemResources) {
            File file = new File("");
            String resourceFolder = file.getAbsolutePath() + "/src/main/resources/static/";
            LOGGER.info("Dev run: using filesystem resource folder: {}", resourceFolder);
            return RouterFunctions.resources("/**", new FileSystemResource(resourceFolder));
        }

        return RouterFunctions.resources("/*", new ClassPathResource("static/"));
    }

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http
                //.csrf().csrfTokenRepository(new WebSessionServerCsrfTokenRepository()).and()
                .csrf().disable()
                .headers()
                    .frameOptions().mode(XFrameOptionsServerHttpHeadersWriter.Mode.SAMEORIGIN)
                .and()
                .authorizeExchange()
                    .pathMatchers(CameraProxyRoutes.getProxyPath() + "**").authenticated()
                    .pathMatchers("/*", "/assets/**", "/login", "/nav/login", "/nav/about", "/api/user/status").permitAll()
                    .anyExchange().authenticated()
                .and()
                .formLogin()
                    .loginPage("/nav/login")
                    .requiresAuthenticationMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/login"))
                .and()
                .logout()
                    .logoutUrl("/logout")
                    .logoutSuccessHandler((exchange, authentication) -> {
                        exchange.getExchange().getResponse().setStatusCode(HttpStatus.OK);
                        return Mono.empty();
                    })
                .and()
                .build();
    }
}