My Spring Boot application contains a login verification system that enforces users to register their credentials and verify their email by sending a confirmation form with an "Activate Now" button in their account. Upon the verification completion, the user may enter with their verified credentials in my application.
The latter is implemented on HTTPS on https:localhost:8443 with SSL enabled along with Spring Security.
My problem is as follows:
I want to expose actuator metrics but since I have HTTPS enabled the omonymous URL will be https:localhost:8443/actuator. I want to access that URL from http:localhost:8080/actuator and for that reason I created a second Tomcat connector which somehow solves my problem since I am receiving responce from POSTMAN.
But... As soon as, I create the second Tomcat connector I have to proceed to the verification process all over again from the start which means that the second Tomcat connector, created a second instance of my application, but running on a different port. I am providing a diagram just to help you somehow with my issue.
I want to access the http:localhost:8080/actuator while maintaining the verification process which took place already from the start of my application on https:localhost:8443. Is that possible???
Security Config Class
package com.andrekreou.iot.authentication.security;
import com.andrekreou.iot.authentication.user.ApplicationUserService;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@AllArgsConstructor
@EnableWebSecurity
public class ApplicationSecurityConfig {
private final ApplicationUserService applicationUserService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.requiresChannel()
.antMatchers("/greeting","/actuator/prometheus")
.requiresInsecure()
.and()
.authorizeRequests()
.antMatchers("/api/v*/registration/**","/register*","/login","/registration","/registration-complete","/greeting").permitAll()
//.antMatchers("/show-news-contents").hasRole(ADMIN.name())
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("email")
.permitAll()
.defaultSuccessUrl("/",true)
.failureUrl("/login-error")
.and()
.logout()
.logoutUrl("/logout")
.clearAuthentication(true)
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID","Idea-2e8e7cee")
.logoutSuccessUrl("/login");
return http.build();
}
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider =
new DaoAuthenticationProvider();
provider.setPasswordEncoder(bCryptPasswordEncoder);
provider.setUserDetailsService(applicationUserService);
return provider;
}
}
Main Class
package com.andrekreou.iot;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication
@EnableJpaRepositories
public class IotApplication {
public static void main(String[] args) {
SpringApplication.run(IotApplication.class, args);
}
@Bean
public ServletWebServerFactory servletContainer(@Value("${server.http.port}") int httpPort) {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setPort(httpPort);
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(connector);
return tomcat;
}
}
Application.properties
#Server properties for HTTPS configuration
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:local-ssl.p12
server.ssl.key-store-password=<password>
server.ssl.key-password=<password>
server.servlet.context-path=/
server.ssl.key-alias=local_ssl
server.port=8443
server.http.port=8080
CodePudding user response:
As M. Deinum suggests, it is preferable to avoid such implementations. You have to configure your application.properties file by adding these two lines.
management.server.ssl.enabled=false
management.server.port=8080
Then remove that server.http.port=8080
as well as ServletWebServerFactory
bean declared in your Main class. Finally, add the following path in your antMatchers line in your Security Config class just after authorizeRequests()
.
This way you will have both /actuator/prometheus
in 8443 and 8080 port.
Hope this helps!!!