spring-cloud / spring-cloud-gateway

An API Gateway built on Spring Framework and Spring Boot providing routing and more.
http://cloud.spring.io
Apache License 2.0
4.52k stars 3.32k forks source link

csrf detection failed 302 forward location problem #2383

Open GKennyKwok opened 3 years ago

GKennyKwok commented 3 years ago

Describe the bug When https post login request gateway is forwarded to security processing by http protocol, csrf detects error 302 The location of forward points to http protocol

I use spring gateway with security, and enable csrf. The browser requests to spring gateway with https protocol, The route is defined as lb:http://security-service, Gateway converts https protocol to http and forwards to security processing, When the POST /login login request, csrf detection fails, the returned 302 forward response Location address in the Header is the url of the http protocol, Returning to the browser through the gateway is unchanged. I use PreserveHostHeader and RewriteLocationResponseHeader to no avail. Browser url changed from https protocol request to http protocol request, I need the browser to stay on the https protocol

gateway-service.yaml

server:
  forward-headers-strategy: FRAMEWORK
  port: 443
  ssl:
    enabled: true
    key-store: classpath:**.jks
    key-store-password: **
    key-store-type: jks

spring:
  cloud:
    gateway:
      discovery:
        locator:
          lower-case-service-id: true
      enabled: true
      forwarded:
        enabled: true
      loadbalancer:
        user404: true
      x-forwarded:
        enabled: true
        for-enabled: true
        proto-enabled: true
        host-enabled: true
        port-enabled: true
    nacos:
      discovery:
        server-addr: **:8848
        namespace: 40dc1346-885b-4921-9da8-138c50ef0384
        group: MODULE_GROUP
    sentinel:
      transport:
        dashboard: **:8081
        port: 8719
      eager: true
      datasource:
        gateway:
          nacos:
            server-addr: **:8848
            namespace: 40dc1346-885b-4921-9da8-138c50ef0384
            group-id: MONITOR_GROUP
            ruleType: gw-flow
            data-type: json
            data-id: gateway-flow-rules.sentinel
            username: **
            password: **
        api:
          nacos:
            server-addr: **:8848
            group-id: MONITOR_GROUP
            namespace: 40dc1346-885b-4921-9da8-138c50ef0384
            ruleType: gw-api-group
            data-type: json
            data-id: gateway-api-group.sentinel
            username: **
            password: **
  jackson:
    default-property-inclusion: non_null
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
  redis:
    database: 0
    host: **
    port: 6379
    password: **
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: -1ms
  session:
    store-type: redis

nacos:
  gateway:
    route:
      config:
        data-id: gateway-route
        group: GATEWAY_GROUP
        timeout: 30000

feign:
  sentinel:
    enabled: true

management:
  endpoints:
    web:
      exposure:
        include: '*'

gateway-route

[
    ...
    {
        "id":"security-service",
        "uri": "lb:http://security-service",
        "predicates": [
            {
                "name": "Path",
                "args": {
                    "pattern": "/login/**",
                    "pattern1": "/logout/**"
                }
            },
            {
                "name": "Method",
                "args": {
                    "pattern":  "GET",
                    "pattern1": "POST"
                }
            }
        ],
        "filters":[
            {
                "name": "PreserveHostHeader"
            },
            {
                "name": "RewriteLocationResponseHeader"
            }
        ]
    }
    ...
]

SecurityConfiguration

@Override
    
protected void configure(HttpSecurity http) throws Exception {
       
http
    .sessionManagement()
                
        .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
                
        .maximumSessions(3)
                    
            .and()
                
        .and()
            
    .csrf()
                
        .csrfTokenRepository(httpSessionCsrfTokenRepository)

                
        .and()
            
    .formLogin()
                
        .loginPage("/login")
               
        .loginProcessingUrl("/login")
        .and()

    .rememberMe()
         .tokenRepository(redisTokenRepository)
         .userDetailsService(userDetailsService)

         .and()
            
    .logout()

         .logoutUrl("/logout")
         .invalidateHttpSession(true)

         .and()

    .authorizeRequests()

         .antMatchers("/login","/logout")

         .permitAll()

         .anyRequest()

         .authenticated()
         .and()
    .anonymous()
         .and();
}
spencergibb commented 2 years ago

The RewriteLocationResponseHeader does not change the scheme