1. Introdução
Este artigo irá apresentar como implementar o redirecionamento de Http para Https por meio de código no Springboot. Este artigo explica apenas o caso do Tomcat como um contêiner. Outros contêineres serão reunidos no futuro.
2. Conceitos relacionados
2.1 O que é redirecionamento
O chamado redirecionamento significa que você queria navegar originalmente pelo endereço A, mas depois de chegar ao servidor, o servidor pensa que a interface do endereço A não está mais lá ou você não tem permissão para acessá-la. Ele não quer que você visite o endereço A; basta informar outro endereço B, Então você vai visitar o endereço B.
Geralmente, existem dois códigos de retorno para redirecionamento:
- 301: Redirecionamento permanente;
- 302: Redirecionamento temporário.
Verifique os detalhes da rede por meio do Chrome e registre o redirecionamento de vários sites:
local na rede Internet | nome do domínio | Código de redirecionamento | URL após redirecionamento |
---|---|---|---|
Fale devagar sobre abóbora | www.pkslow.com | 301 | https://www.pkslow.com |
www.google.com | 307 | https://www.google.com | |
maçã | www.apple.com | 307 | https://www.apple.com |
Alipay | www.alipay.com | 301 | https://www.alipay.com |
www.qq.com | 302 | https://www.qq.com | |
Baidu | www.baidu.com | 307 | https://www.baidu.com |
Nota: 307 também é um tipo de redirecionamento, que é um novo código de status.
2.2 Por que redirecionar
Combinado com a tabela que listei especificamente acima, você provavelmente pensa em por que esse tipo de redirecionamento é necessário? Não é difícil descobrir que o redirecionamento acima está fazendo uma coisa, ou seja, redirecionando http para https. As razões são as seguintes:
(1) http não é seguro, você deve usar um URL https seguro;
(2) Mas você não pode pedir aos usuários que digitem https: // toda vez que entrarem em um site. Isso é muito problemático, então todos estão acostumados a inserir apenas o nome de domínio, nem mesmo www .. Portanto, a entrada do usuário é, na verdade, para acessar a página da web http e precisa ser redirecionada para https para atender aos requisitos de acesso seguro.
2.3 Como redirecionar
Em primeiro lugar, o servidor deve suportar http e https ao mesmo tempo, caso contrário não haverá redirecionamento. Como o https é necessário para fornecer suporte, por que fornecer serviços http? Não é simplesmente desnecessário visitar https diretamente? O motivo foi mencionado antes. Todos estão acostumados a inserir apenas um nome de domínio simples para visitar. No momento, é http. Se você não fornecer suporte para http, os usuários pensam que seu site já está fora do ar.
Ambos os protocolos oferecem suporte, por isso é necessário abrir duas portas Socket.Geralmente, http é 80 e https é 443. Em seguida, você precisa redirecionar todas as solicitações HTTP para https. Servidores diferentes têm implementações diferentes. Agora, introduza a implementação do Springboot + Tomcat.
3. Springboot Tomcat implementa redirecionamento
Quando o Springboot usa o Tomcat como o contêiner do Servlet, há duas maneiras de obter o redirecionamento, uma sem Spring Security e a outra com Spring Security. A estrutura do código é a seguinte: o
código da classe principal é o seguinte:
package com.pkslow.ssl;
import com.pkslow.ssl.config.containerfactory.HttpToHttpsContainerFactoryConfig;
import com.pkslow.ssl.config.security.EnableHttpWithHttpsConfig;
import com.pkslow.ssl.config.security.HttpToHttpsWebSecurityConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import({
EnableHttpWithHttpsConfig.class, HttpToHttpsWebSecurityConfig.class})
//@Import(HttpToHttpsContainerFactoryConfig.class)
@ComponentScan(basePackages = "com.pkslow.ssl.controller")
public class SpringbootSslApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootSslApplication.class, args);
}
}
@ComponentScan (basePackages = "com.pkslow.ssl.controller"): O pacote de configuração não é varrido porque queremos usar @Import para controlar para que lado redirecionar. Obviamente, você também pode usar outros métodos de controle, como @ConditionalOnProperty, que não será discutido aqui.
- Quando Spring Security não é usado, @Import (HttpToHttpsContainerFactoryConfig.class) é usado;
- Ao usar Spring Security, use @Import ({EnableHttpWithHttpsConfig.class,
HttpToHttpsWebSecurityConfig.class}).
O conteúdo do arquivo de configuração application.properties é o seguinte:
server.port=443
http.port=80
server.ssl.enabled=true
server.ssl.key-store-type=jks
server.ssl.key-store=classpath:localhost.jks
server.ssl.key-store-password=changeit
server.ssl.key-alias=localhost
É necessário especificar duas portas, server.port é a porta https; http.port é a porta http. Observe que, na ausência de https, server.port se refere à porta http.
3.1 Configurar o Container Factory para implementar o redirecionamento
A classe configurada é HttpToHttpsContainerFactoryConfig, o código é o seguinte:
package com.pkslow.ssl.config.containerfactory;
import org.apache.catalina.Context;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpToHttpsContainerFactoryConfig {
@Value("${server.port}")
private int httpsPort;
@Value("${http.port}")
private int httpPort;
@Bean
public TomcatServletWebServerFactory 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(createHttpConnector());
return tomcat;
}
private Connector createHttpConnector() {
Connector connector =
new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setSecure(false);
connector.setPort(httpPort);
connector.setRedirectPort(httpsPort);
return connector;
}
}
createHttpConnector (): Este método realiza principalmente a função de abrir http sob a premissa de https e configurar a porta https redirecionada.
3.2 Configure a segurança Spring para implementar o redirecionamento
Existem duas classes de configuração, uma para abrir o serviço http e outra para implementar o redirecionamento.
A principal função de EnableHttpWithHttpsConfig é abrir o serviço http sob a premissa de ter https.
package com.pkslow.ssl.config.security;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration
public class EnableHttpWithHttpsConfig {
@Value("${http.port}")
private int httpPort;
@Component
public class CustomContainer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setPort(httpPort);
connector.setScheme("http");
connector.setSecure(false);
factory.addAdditionalTomcatConnectors(connector);
}
}
}
HttpToHttpsWebSecurityConfig é principalmente para a configuração do Spring Security.Como todos sabemos, Spring Security é muito poderoso, mas muito complicado. Os principais comentários foram escritos no código:
package com.pkslow.ssl.config.security;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class HttpToHttpsWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${server.port}")
private int httpsPort;
@Value("${http.port}")
private int httpPort;
@Override
protected void configure(HttpSecurity http) throws Exception {
//redirect to https - 用spring security实现
http.portMapper().http(httpPort).mapsTo(httpsPort);
http.requiresChannel(
channel -> channel.anyRequest().requiresSecure()
);
//访问路径/hello不用登陆获得权限
http.authorizeRequests()
.antMatchers("/hello").permitAll()
.anyRequest().authenticated().and();
}
@Override
public void configure(WebSecurity web) throws Exception {
//过滤了actuator后,不会重定向,也不用权限校验,这个功能非常有用
web.ignoring()
.antMatchers("/actuator")
.antMatchers("/actuator/**");
}
}
Conclusão:
Os amigos que precisam aprender os materiais podem clicar para entrar, senha: cspp , baixe de graça!