Spring Boot应用能否为不同@RequestMapping配置HTTP/HTTPS访问?
Absolutely, you can absolutely set up your Spring application to handle both HTTP and HTTPS requests separately—perfect for your use case where microcontrollers can't handle SSL, but Android clients need the security of HTTPS. Let's break down how to implement this:
Step 1: Configure Both Ports in Your Application Properties
First, define ports for both HTTP (for MCUs) and HTTPS (for Android) in your application.properties (or application.yml):
# HTTPS Configuration (for Android clients) server.port=8443 server.ssl.key-store=classpath:your-keystore.jks server.ssl.key-store-password=your-keystore-password server.ssl.key-password=your-key-password server.ssl.key-alias=your-key-alias # HTTP Configuration (for microcontrollers) server.http.port=8080
If you prefer YAML:
server: port: 8443 ssl: key-store: classpath:your-keystore.jks key-store-password: your-keystore-password key-password: your-key-password key-alias: your-key-alias http: port: 8080
Step 2: Enable the HTTP Connector Programmatically
Spring only enables the HTTPS port by default when SSL is configured. To spin up the HTTP port alongside it, create a configuration class to add an additional Tomcat connector:
@Configuration public class DualPortConfig { @Value("${server.http.port}") private int httpPort; @Bean public ServletWebServerFactory servletWebServerFactory() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); tomcat.addAdditionalTomcatConnectors(createHttpConnector()); return tomcat; } private Connector createHttpConnector() { Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); connector.setPort(httpPort); // No need for redirects here since MCUs can't handle HTTPS anyway return connector; } }
Step 3: Secure Endpoints Appropriately
To enforce that Android clients use HTTPS and restrict access to MCU endpoints, use Spring Security to set channel requirements and access rules:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth // Allow unauthenticated access to MCU-specific endpoints (adjust paths to match your API) .requestMatchers("/api/mcu/**").permitAll() // Require authentication for Android client endpoints .requestMatchers("/api/android/**").authenticated() .anyRequest().denyAll() ) // Force Android endpoints to use HTTPS only .requiresChannel(channel -> channel .requestMatchers("/api/android/**").requiresSecure() ); return http.build(); } }
Key Considerations
- Lock Down the HTTP Port: Ensure the HTTP port (e.g., 8080) is only accessible within your local network—never expose it to the public internet. Unencrypted HTTP traffic over the web is a critical security risk.
- Add Lightweight Encryption for MCUs (If Needed): If your MCUs need to send data over the internet (not just local), implement simple symmetric encryption (like AES) on the device, then decrypt the payload in your Spring app. This adds a security layer without requiring SSL on the MCU.
- Generate a Keystore: If you don't have a keystore for HTTPS, create one with the
keytoolcommand:keytool -genkeypair -alias myapp-key -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
内容的提问来源于stack exchange,提问作者Alexandru Antochi

