Pour les applications basées sur Spring Boot, j'ai configuré les propriétés SSL sur application.properties, voir ma configuration ici:
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
Et j'ai ajouté la connexion à Application.class, comme
@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;
}
Mais quand j'essaye ce qui suit par
http://127.0.0.1:9090/
rediriger vers
https://127.0.0.1:8443/
n'est pas effectuée. Qui a fait face à un problème similaire?
Pour que Tomcat effectue une redirection, vous devez la configurer avec une ou plusieurs contraintes de sécurité. Vous pouvez le faire en post-traitant la Context
à l'aide d'une sous-classe TomcatEmbeddedServletContainerFactory
.
Par exemple:
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);
}
};
En raison de CONFIDENTIAL
et /*
, Tomcat redirigera chaque demande vers HTTPS. Vous pouvez configurer plusieurs modèles et plusieurs contraintes si vous avez besoin de plus de contrôle sur ce qui est et n'est pas redirigé.
Définir cette propriété sur votre fichier d'application * .properties (et la configuration spécifique au servlet correspondante pour les en-têtes HTTPS dans le cas où vous exécutez derrière un proxy) et avoir la configuration de Spring Security (par exemple, avoir org.springframework.boot: spring-boot-starter-security sur votre chemin de classe) devrait suffire:
security.require-ssl=true
Maintenant, pour une raison quelconque, la configuration n'est pas respectée lorsque l'authentification de base est désactivée (au moins sur les anciennes versions de Spring Boot). Donc, dans ce cas, vous devrez prendre une étape supplémentaire et l'honorer vous-même en configurant manuellement la sécurité de votre code, comme ceci:
@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();
}
}
Donc, au cas où vous utilisez Tomcat derrière un proxy, vous auriez toutes ces propriétés sur votre fichier d'application * .properties:
security.require-ssl=true
server.Tomcat.remote_ip_header=x-forwarded-for
server.Tomcat.protocol_header=x-forwarded-proto
La réponse approuvée ne m'a pas suffi.
J'ai également dû ajouter ce qui suit à ma configuration de sécurité Web, car je n'utilise pas le port 8080 par défaut:
@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();
}
}
Suivez seulement 2 étapes.
1- Ajouter une dépendance de sécurité Spring dans pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2- Ajoutez cette classe sur le package racine de votre application.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().anyRequest().requiresSecure();
}
}
Dans Spring-Boot, besoin d'une dépendance inférieure
Étape 1-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Étape 2- Il suffit de faire les configurations ci-dessous sur le fichier application.properties
- server.port=8443
- server.ssl.key.alias=ode-https
- server.ssl.key-store-type=JKS (just for testing i USED JSK, but for production normally use pkcs12)
- server.ssl.key-password=password
- server.ssl.key-store=classpath:ode-https.jks
L'étape 3 doit maintenant générer un certificat en utilisant les détails ci-dessus.
keytool -genkey -alias ode-https -storetype JKS -keyalg RSA -keys ize 2048 -validity 365 -keystore ode-https.jks
Étape 4 - déplacez le certificat vers le dossier des ressources de votre programme.
Étape 5- Créer une classe de configuration
@Configuration
public class HttpsConfiguration {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory Tomcat = new TomcatServletWebServerFactory() {
@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);
}
};
Tomcat.addAdditionalTomcatConnectors(redirectConnector());
return Tomcat;
}
@Value("${server.port.http}") //Defined in application.properties file
int httpPort;
@Value("${server.port}") //Defined in application.properties file
int httpsPort;
private Connector redirectConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(httpPort);
connector.setSecure(false);
connector.setRedirectPort(httpsPort);
return connector;
}
}
c'est ça.
Depuis TomcatEmbeddedServletContainerFactory
a été supprimé dans Spring Boot 2, utilisez ceci:
@Bean
public TomcatServletWebServerFactory httpsRedirectConfig() {
return new TomcatServletWebServerFactory () {
@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);
}
};
}
Pour Jetty (testé avec 9.2.14), vous devez ajouter une configuration supplémentaire au WebAppContext
(ajustez le pathSpec
à votre goût):
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);
}
}
Câblez ensuite cette classe en ajoutant un @Configuration
classe implémentant EmbeddedServletContainerCustomizer
avec un nouveau Connector
qui écoute le port non sécurisé:
@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);
});
}
}
Cela implique que SSL Connector
est déjà configuré et écoute sur le port 443 dans cet exemple.