问题
I'm running a Spring boot (Jhipster/Undertow) application on port 8080 on an AWS EC2 instance.
I have an AWS ELB configured to redirect
80 -> 8080
443 (SSL termination happens here) -> 8080
The application uses Spring Security and if you user arrives to http://example.com I want it to redirect to https://example.com, to use SSL.
I have found various examples of configuring this in Tomcat but none using Undertow.
I have tried this, with a second port 8089, and it does redirect as required, but this causes port 8080 to also redirects which I don't want.
80 -> 8089
443 (SSL termination happens here) -> 8080
@Bean
public EmbeddedServletContainerFactory undertow() {
UndertowEmbeddedServletContainerFactory undertow = new UndertowEmbeddedServletContainerFactory();
undertow.addBuilderCustomizers(builder -> builder.addHttpListener(8089, "0.0.0.0"));
undertow.addDeploymentInfoCustomizers(deploymentInfo -> {
deploymentInfo.addSecurityConstraint(new SecurityConstraint()
.addWebResourceCollection(new WebResourceCollection()
.addUrlPattern("/*"))
.setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL)
.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT))
.setConfidentialPortManager(exchange -> 443);
});
return undertow;
}
How can I configure Undertow to achieve this?
回答1:
This worked for me when I had the same problem:
Expose the port 80 from jhipster (you can change it in the application-prod.yml
).
Amazon ELB when redirecting from http to https adds some headers, which you should address in the same file:
server:
use-forward-headers: true
port: 80
Also, you need to enforce the https from jhipster: https://jhipster.github.io/tips/007_tips_enforce_https.html
回答2:
Just in case if somebody wants a working solution for redirecting all http requests to https with HTTP/2 in Spring Boot 1.5.19, following is the setting in application.properties
file:
server.ssl.protocol=TLSv1.2
server.ssl.key-store-type=PKCS12
server.ssl.key-store=keystore.p12
server.ssl.key-store-password=xxxxxxx
server.port=443
server.use-forward-headers=true
And the following Java configuration:
import io.undertow.UndertowOptions;
import io.undertow.servlet.api.SecurityConstraint;
import io.undertow.servlet.api.SecurityInfo;
import io.undertow.servlet.api.TransportGuaranteeType;
import io.undertow.servlet.api.WebResourceCollection;
import org.springframework.boot.context.embedded.undertow.UndertowBuilderCustomizer;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
public class ConnectorConfig {
@Bean
public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
factory.addBuilderCustomizers((UndertowBuilderCustomizer) builder -> {
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
builder.addHttpListener(80, "0.0.0.0");
});
factory.addDeploymentInfoCustomizers(deploymentInfo -> {
deploymentInfo.addSecurityConstraint(
new SecurityConstraint()
.addWebResourceCollection(new WebResourceCollection().addUrlPattern("/*"))
.setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL)
.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT))
.setConfidentialPortManager(exchange -> 443);
});
return factory;
}
}
Everything will be working perfectly.
来源:https://stackoverflow.com/questions/42741194/spring-boot-with-embedded-undertow-behind-aws-elb-http-to-https-redirect