2014-10-30 16 views
21

Per un'applicazione basata Primavera Boot ho configurared proprietà ssl a application.properties, vedere la mia configurazione qui:Primavera Boot reindirizzamento HTTP a HTTPS

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 

E ho aggiunto conection a Application.class, come

@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; 
} 

Ma quando provo il seguente da

http://127.0.0.1:9090/ 

reindirizzare a

https://127.0.0.1:8443/ 

non eseguito. Chi ha affrontato un problema simile?

risposta

23

Perché Tomcat esegua un reindirizzamento, è necessario configurarlo con uno o più vincoli di sicurezza. È possibile eseguire questa operazione post-elaborazione dello Context utilizzando una sottoclasse TomcatEmbeddedServletContainerFactory.

Ad esempio:

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); 
    } 
}; 

causa CONFIDENTIAL e /*, questo farà sì che Tomcat reindirizzare ogni richiesta di HTTPS. È possibile configurare più schemi e più vincoli se è necessario un maggiore controllo su ciò che è e non viene reindirizzato.

+6

c'è un approccio simile per Jetty? – checketts

+0

Qual è il posto appropriato per questo snippet di codice? – Jelle

+0

Come mostrato nella domanda, 'TomcatEmbeddedServletContainerFactory' deve essere esposto come bean in una classe di configurazione. –

3

Per Jetty (testato con 9.2.14), è necessario aggiungere una configurazione di più per il WebAppContext (regolare la pathSpec al vostro 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); 
    } 
} 

Poi filo questa classe con l'aggiunta di una classe che implementa @ConfigurationEmbeddedServletContainerCustomizer insieme a un nuovo Connector che ascolta la porta non sicura:

@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); 
     }); 
    } 
} 

Ciò implica che il protocollo SSL Connector è già configurato e in ascolto sulla porta 443 in questo esempio.

19

Impostazione di questa proprietà sull'applicazione * .properties file (e la configurazione specifica del servlet corrispondente per le intestazioni HTTPS nel caso in cui si esegua dietro un proxy) e con impostazione Spring Security (ad esempio con org.springframework.boot : primavera-boot-starter-sicurezza sul classpath) dovrebbe essere sufficiente:

security.require-ssl=true 

Ora, per qualche ragione che la configurazione non è onorato, quando l'autenticazione di base è disattivato (almeno su vecchie versioni di primavera di avvio). Quindi, in questo caso si avrebbe bisogno di fare un passo in più e onorare voi stessi configurando manualmente la sicurezza del codice, in questo modo:

@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(); 
    } 
} 

Quindi, nel caso in cui si utilizza Tomcat dietro un proxy, si avrebbe tutte queste proprietà sull'applicazione * .properties file:

security.require-ssl=true 

server.tomcat.remote_ip_header=x-forwarded-for 
server.tomcat.protocol_header=x-forwarded-proto 
+0

La tua risposta mi ha salvato la giornata! –

+0

ha funzionato per me con AWS cert su Load Balancer – jarosik

+0

Le intestazioni forwarded * possono anche essere abilitate con server.use-forward-headers = true –

6

La risposta approvata non è stata sufficiente per me.

ho dovuto aggiungere anche il seguente al mio config sicurezza web, come io non sto usando la porta di default 8080:

@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(); 
    } 
} 
+1

La soluzione migliore e non dipende da quale server incorporato si utilizza – lrn2prgrm

2

solo seguire 2 fasi.

1- Aggiungi dipendenza sicurezza primavera in pom.xml

<dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-security</artifactId> 
    </dependency> 

2- Aggiungi questa classe sul package principale della vostra applicazione.

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.requiresChannel().anyRequest().requiresSecure(); 
    } 
} 
Problemi correlati