Spring Boot OAuth 始终重定向到 HTTP(IBM Cloud CF + Spring Boot 2) [英] Spring Boot OAuth Always redirecting to HTTP (IBM Cloud CF + Spring Boot 2)

查看:43
本文介绍了Spring Boot OAuth 始终重定向到 HTTP(IBM Cloud CF + Spring Boot 2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 IBM Cloud CF Java Buildpack 上使用 Spring Boot OAuth 2...

Using Spring Boot OAuth 2 on IBM Cloud CF Java Buildpack...

https://github.com/ericis/oauth-cf-https-issue

*我已经尝试了以下所有组合.

*I have tried every combination of the below.

使用这个配置,应用程序陷入无限的重定向循环中,OAuth重定向策略将它发送到http,然后这个配置将它发送到https.

With this configuration, the application is stuck in an endless loop of redirects, where the OAuth redirect strategy sends it to http and then this configuration sends it to https.

http.requiresChannel().anyRequest().requiresSecure()

没有这个配置,用户可以通过http登录(不需要).

Without this configuration, users can login via http (undesired).

完整配置:

http.
  requiresChannel().anyRequest().requiresSecure().
  authorizeRequests().
    // allow access to...
    antMatchers("favicon.ico", "/login", "/loginFailure", "/oauth2/authorization/ghe")
    .permitAll().anyRequest().authenticated().and().oauth2Login().
    // Codify "spring.security.oauth2.client.registration/.provider"
    clientRegistrationRepository(this.clientRegistrationRepository()).
    // setup OAuth2 client service to use clientRegistrationRepository
    authorizedClientService(this.authorizedClientService()).
    successHandler(this.successHandler()).
    // customize login pages
    loginPage("/login").failureUrl("/loginFailure").
    userInfoEndpoint().
      // customize the principal
      userService(this.userService());

我也试过:

  1. 使用https

server:
  useForwardHeaders: true
  tomcat:
    protocolHeader: x-forwarded-proto

  • Servlet 过滤器

  • Servlet filter

    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    @Component
    public class HttpToHttpsFilter implements Filter {
    
      private static final Logger log = LoggerFactory.getLogger(HttpToHttpsFilter.class);
    
      private static final String HTTP = "http";
      private static final String SCHEME_HTTP = "http://";
      private static final String SCHEME_HTTPS = "https://";
      private static final String LOCAL_ID = "0:0:0:0:0:0:0:1";
      private static final String LOCALHOST = "localhost";
    
      @Value("${local.ip}")
      private String localIp;
    
      public HttpToHttpsFilter() {
        // Sonar
      }
    
      @Override
      public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
          throws IOException, ServletException {
    
        final HttpServletRequest request = (HttpServletRequest) req;
    
        final HttpServletResponse response = (HttpServletResponse) res;
    
        // http, not localhost, not localhost ipv6, not local IP
        if (HTTP.equals(request.getScheme()) && 
            !LOCALHOST.equals(request.getRemoteHost()) && 
            !LOCAL_ID.equals(request.getRemoteHost()) && 
            (this.localIp != null && !this.localIp.equals(request.getRemoteHost()))) {
    
          final String query = request.getQueryString();
    
          String oldLocation = request.getRequestURL().toString();
    
          if (query != null) {
            oldLocation += "?" + query;
          }
    
          final String newLocation = oldLocation.replaceFirst(SCHEME_HTTP, SCHEME_HTTPS);
    
          try {
    
            log.info("HTTP redirect from {} to {} ", oldLocation, newLocation);
    
            response.sendRedirect(newLocation);
    
          } catch (IOException e) {
            log.error("Cannot redirect to {} {} ", newLocation, e);
          }
        } else {
          chain.doFilter(req, res);
        }
      }
    
      @Override
      public void destroy() {
        // Sonar
      }
    
      @Override
      public void init(FilterConfig arg0) throws ServletException {
        // Sonar
      }
    }
    

  • 依赖关系

    dependencies {
    
        //
        // BASICS
    
        // health and monitoring
        // compile('org.springframework.boot:spring-boot-starter-actuator')
    
        // security
        compile('org.springframework.boot:spring-boot-starter-security')
    
        // configuration
        compile('org.springframework.boot:spring-boot-configuration-processor')
    
      //
      // WEB
    
      // web
      compile('org.springframework.boot:spring-boot-starter-web')
    
      // thymeleaf view render
      compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    
      // thymeleaf security extras
      compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4')
    
      //
      // OAUTH
    
      // OAuth client
      compile('org.springframework.security:spring-security-oauth2-client')
    
      // OAuth lib
      compile('org.springframework.security:spring-security-oauth2-jose')
    
      // OAuth config
      compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.0.RELEASE')
    
      //
      // CLOUD
    
      // cloud connectors (e.g. vcaps)
      compile('org.springframework.boot:spring-boot-starter-cloud-connectors')
    
        //
        // TOOLS
    
        runtime('org.springframework.boot:spring-boot-devtools')
    
        //
        // TEST
    
        // test
        testCompile('org.springframework.boot:spring-boot-starter-test')
    
        // security test
        testCompile('org.springframework.security:spring-security-test')
    }
    

    推荐答案

    此问题已解决.有关与此相关的问题的详细信息,请访问:https://github.com/spring-projects/spring-security/issues/5535#issuecomment-407413944

    This was resolved. Details on the issue related to this can be found at: https://github.com/spring-projects/spring-security/issues/5535#issuecomment-407413944

    正在运行的示例项目:https://github.com/ericis/oauth-cf-https-issue

    简短的回答:

    需要明确配置应用程序以了解代理标头.我曾尝试过配置,但最终不得不使用 ForwardedHeaderFilter 类的一个实例,该实例是最近添加到 Spring 中的.

    The application needs to be explicitly configured to be aware of the proxy headers. I had tried configuration, but ultimately had to use an instance of the ForwardedHeaderFilter class that was added fairly recently to Spring.

    @Bean
    FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
    
        final FilterRegistrationBean<ForwardedHeaderFilter> filterRegistrationBean = new FilterRegistrationBean<ForwardedHeaderFilter>();
    
        filterRegistrationBean.setFilter(new ForwardedHeaderFilter());
        filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    
        return filterRegistrationBean;
    }
    

    这篇关于Spring Boot OAuth 始终重定向到 HTTP(IBM Cloud CF + Spring Boot 2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆