java - combination - Spring Boot redirige HTTP a HTTPS
spring boot https (5)
Establecer esta propiedad en el archivo * .properties de la aplicación (y la configuración específica de servlet correspondiente para los encabezados HTTPS en caso de que se esté ejecutando detrás de un proxy) y tener la configuración de Spring Security (por ejemplo, tener org.springframework.boot: spring-boot- starter-security en su classpath) debería ser suficiente:
security.require-ssl=true
Ahora, por algún motivo, no se respeta la configuración cuando la autenticación básica está desactivada (al menos en las versiones anteriores de Spring Boot). Entonces, en ese caso, necesitaría dar un paso más y cumplirlo usted mismo configurando manualmente la seguridad en su código, así:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Inject private SecurityProperties securityProperties;
@Override
protected void configure(HttpSecurity http) throws Exception {
if (securityProperties.isRequireSsl()) http.requiresChannel().anyRequest().requiresSecure();
}
}
Entonces, en caso de que esté usando Tomcat detrás de un proxy, tendría todas estas propiedades en su archivo de solicitud * .properties:
security.require-ssl=true
server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
Para la aplicación basada en Spring Boot, he configurado las propiedades de ssl en application.properties, vea mi configuración aquí:
server.port=8443
server.ssl.key-alias=tomcat
server.ssl.key-password=123456
server.ssl.key-store=classpath:key.p12
server.ssl.key-store-provider=SunJSSE
server.ssl.key-store-type=pkcs12
Y he agregado la conexión en Application.class, como
@Bean
public EmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
final TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addAdditionalTomcatConnectors(this.createConnection());
return factory;
}
private Connector createConnection() {
final String protocol = "org.apache.coyote.http11.Http11NioProtocol";
final Connector connector = new Connector(protocol);
connector.setScheme("http");
connector.setPort(9090);
connector.setRedirectPort(8443);
return connector;
}
Pero cuando intento lo siguiente por
http://127.0.0.1:9090/
redirigir a
https://127.0.0.1:8443/
no se realiza ¿Quién se enfrentó a un problema similar?
La respuesta aprobada no fue suficiente para mí.
También tuve que agregar lo siguiente a mi configuración de seguridad web, ya que no estoy usando el puerto 8080 predeterminado:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private Environment environment;
@Override
public void configure(HttpSecurity http) throws Exception {
// other security configuration missing
http.portMapper()
.http(Integer.parseInt(environment.getProperty("server.http.port"))) // http port defined in yml config file
.mapsTo(Integer.parseInt(environment.getProperty("server.port"))); // https port defined in yml config file
// we only need https on /auth
http.requiresChannel()
.antMatchers("/auth/**").requiresSecure()
.anyRequest().requiresInsecure();
}
}
Para Jetty (probado con 9.2.14), necesita agregar una configuración adicional al WebAppContext
(ajuste pathSpec
a su gusto):
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
class HttpToHttpsJettyConfiguration extends AbstractConfiguration
{
// http://wiki.eclipse.org/Jetty/Howto/Configure_SSL#Redirecting_http_requests_to_https
@Override
public void configure(WebAppContext context) throws Exception
{
Constraint constraint = new Constraint();
constraint.setDataConstraint(2);
ConstraintMapping constraintMapping = new ConstraintMapping();
constraintMapping.setPathSpec("/*");
constraintMapping.setConstraint(constraint);
ConstraintSecurityHandler constraintSecurityHandler = new ConstraintSecurityHandler();
constraintSecurityHandler.addConstraintMapping(constraintMapping);
context.setSecurityHandler(constraintSecurityHandler);
}
}
A continuación, conecte esta clase agregando una clase @Configuration
implemente EmbeddedServletContainerCustomizer
junto con un nuevo Connector
que escuche el puerto no seguro:
@Configuration
public class HttpToHttpsJettyCustomizer implements EmbeddedServletContainerCustomizer
{
@Override
public void customize(ConfigurableEmbeddedServletContainer container)
{
JettyEmbeddedServletContainerFactory containerFactory = (JettyEmbeddedServletContainerFactory) container;
//Add a plain HTTP connector and a WebAppContext config to force redirect from http->https
containerFactory.addConfigurations(new HttpToHttpsJettyConfiguration());
containerFactory.addServerCustomizers(server -> {
HttpConfiguration http = new HttpConfiguration();
http.setSecurePort(443);
http.setSecureScheme("https");
ServerConnector connector = new ServerConnector(server);
connector.addConnectionFactory(new HttpConnectionFactory(http));
connector.setPort(80);
server.addConnector(connector);
});
}
}
Esto implica que el Connector
SSL ya está configurado y escuchando en el puerto 443 en este ejemplo.
Para que Tomcat realice una redirección, debe configurarla con una o más restricciones de seguridad. Puede hacerlo procesando posteriormente el Context
utilizando una subclase TomcatEmbeddedServletContainerFactory
.
Por ejemplo:
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
Debido a CONFIDENTIAL
y /*
, esto hará que Tomcat redirija cada solicitud a HTTPS. Puede configurar múltiples patrones y múltiples restricciones si necesita más control sobre lo que se redirecciona y lo que no.
Siga solo 2 pasos.
1- Agregar dependencia de seguridad de primavera en pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2- Agregue esta clase en el paquete raíz de su aplicación.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().anyRequest().requiresSecure();
}
}