2014-10-30 48 views
21

Đối với mùa xuân Boot dựa trên ứng dụng tôi đã configurared tính ssl tại application.properties, xem cấu hình của tôi ở đây:Xuân Boot chuyển hướng HTTP thành 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 

Và tôi đã thêm conection tại Application.class, như

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

Nhưng khi tôi thử những điều sau đây bởi

http://127.0.0.1:9090/ 

chuyển hướng đến

https://127.0.0.1:8443/ 

không được thực hiện. Ai phải đối mặt với một vấn đề tương tự?

Trả lời

23

Để Tomcat thực hiện chuyển hướng, bạn cần phải định cấu hình nó bằng một hoặc nhiều ràng buộc bảo mật. Bạn có thể thực hiện việc này bằng cách xử lý sau Context bằng cách sử dụng lớp con TomcatEmbeddedServletContainerFactory.

Ví dụ:

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

Do CONFIDENTIAL/*, điều này sẽ gây ra Tomcat để chuyển hướng mọi yêu cầu HTTPS. Bạn có thể cấu hình nhiều mẫu và nhiều ràng buộc nếu bạn cần kiểm soát nhiều hơn những gì được và không được chuyển hướng.

+6

có cách tiếp cận tương tự cho Jetty không? – checketts

+0

Vị trí thích hợp cho đoạn mã này là gì? – Jelle

+0

Như được hiển thị trong câu hỏi, 'TomcatEmbeddedServletContainerFactory' sẽ được hiển thị dưới dạng bean trong lớp cấu hình. –

3

Đối Jetty (thử nghiệm với 9.2.14), bạn cần phải thêm một cấu hình bổ sung cho các WebAppContext (điều chỉnh pathSpec để khẩu vị của bạn):

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

Sau đó dây lớp này bằng cách thêm một lớp @Configuration thực hiện EmbeddedServletContainerCustomizer cùng với một mới Connector rằng lắng nghe những cổng không an toàn:

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

Điều này ngụ ý rằng SSL Connector đã được cấu hình và lắng nghe trên cổng 443 trong ví dụ này.

19

Đặt thuộc tính này trên ứng dụng của bạn * tệp .properties (và cấu hình tương ứng của servlet cho tiêu đề HTTPS trong trường hợp bạn đang chạy sau proxy) và thiết lập Bảo mật mùa xuân (ví dụ: org.springframework.boot : mùa xuân-boot-khởi-an ninh trên classpath của bạn) nên đủ:

security.require-ssl=true 

Bây giờ, đối với một số lý do cấu hình mà không được vinh danh khi xác thực cơ bản bị vô hiệu hóa (ít nhất là trên các phiên bản cũ của mùa xuân boot). Vì vậy, trong trường hợp đó bạn sẽ cần phải thực hiện thêm một bước và tôn vinh nó cho mình bằng cách thủ công cấu hình bảo mật trên mã của bạn, như thế này:

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

Vì vậy, trong trường hợp bạn đang sử dụng Tomcat sau một proxy, bạn sẽ phải tất cả các thuộc tính này trong ứng dụng của bạn * .properties file:

security.require-ssl=true 

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

Câu trả lời của bạn đã cứu được ngày của tôi! –

+0

đã làm việc cho tôi với chứng nhận AWS về Cân bằng tải – jarosik

+0

Các tiêu đề được chuyển tiếp cũng có thể được bật với server.use-forward-headers = true –

6

Câu trả lời được chấp thuận là không đủ cho tôi.

tôi cũng đã thêm phần sau đây để cấu hình bảo mật web của tôi, như tôi không sử dụng cổng mặc định 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

Giải pháp tốt nhất và nó không phụ thuộc vào máy chủ nhúng bạn sử dụng – lrn2prgrm

2

Làm theo chỉ có 2 bước.

1- Add phụ thuộc an ninh mùa xuân trong pom.xml

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

2- Thêm lớp này trên bao bì gốc của ứng dụng của bạn.

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.requiresChannel().anyRequest().requiresSecure(); 
    } 
} 
Các vấn đề liên quan