web-dev-qa-db-ja.com

HTTPからHTTPSへのSpring Bootリダイレクト

Spring Bootベースのアプリケーションの場合、application.propertiesでsslプロパティを設定しました。ここで私の設定を参照してください:

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

そして、次のようにApplication.classに接続を追加しました

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

しかし、次のことを試してみると

http://127.0.0.1:9090/

にリダイレクト

https://127.0.0.1:8443/

実行されません。誰が同様の問題に直面しましたか?

32

Tomcatでリダイレクトを実行するには、1つ以上のセキュリティ制約を設定してリダイレクトする必要があります。これを行うには、Contextサブクラスを使用してTomcatEmbeddedServletContainerFactoryを後処理します。

例えば:

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

CONFIDENTIALおよび/*、これによりTomcatはすべてのリクエストをHTTPSにリダイレクトします。リダイレクトされるものとされないものをさらに制御する必要がある場合は、複数のパターンと複数の制約を構成できます。

31
Andy Wilkinson

Application * .propertiesファイル(およびプロキシの背後で実行している場合は対応するHTTPSヘッダーの対応するサーブレット固有の設定)でこのプロパティを設定し、Spring Securityをセットアップします(たとえば、org.springframework.boot:クラスパスのspring-boot-starter-securityで十分です:

security.require-ssl=true

さて、何らかの理由で、基本認証が無効になっている場合(少なくとも古いバージョンのSpring Bootでは)、構成が尊重されません。したがって、その場合は、次のようにコードのセキュリティを手動で構成することにより、追加の手順を実行して自分でそれを尊重する必要があります。

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

そのため、プロキシの背後でTomcatを使用している場合、application * .propertiesファイルに次のすべてのプロパティがあります。

security.require-ssl=true

server.Tomcat.remote_ip_header=x-forwarded-for
server.Tomcat.protocol_header=x-forwarded-proto
27
Rodrigo Quesada

承認された答えは私には十分ではありませんでした。

また、デフォルトの8080ポートを使用していないため、Webセキュリティ設定に次を追加する必要がありました。

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

2つの手順のみに従ってください。

1- pom.xmlに春のセキュリティ依存関係を追加する

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

2-アプリケーションのルートパッケージにこのクラスを追加します。

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

Spring-Bootでは、以下の依存関係が必要

ステップ1-

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

ステップ2-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

ステップ3-では、上記の詳細を使用して証明書を生成する必要があります。

keytool -genkey -alias ode-https -storetype JKS -keyalg RSA -keys ize 2048 -validity 365 -keystore ode-https.jks

手順4-証明書をプログラムのリソースフォルダーに移動します。

ステップ5-構成クラスを作成する

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

それでおしまい。

6
Arvind Pant

TomcatEmbeddedServletContainerFactoryは削除されました Spring Boot 2では、これを使用します:

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

Jetty(9.2.14でテスト済み)の場合、WebAppContextに追加の構成を追加する必要があります(pathSpecを好みに合わせて調整します):

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

次に、安全でないポートをリッスンする新しいEmbeddedServletContainerCustomizerとともにConnectorを実装する@Configurationクラスを追加して、このクラスを配線します。

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

これは、この例ではSSL Connectorがすでに構成されており、ポート443でリッスンしていることを意味します。

3
jebeaudet