spring-cloud / spring-cloud/spring-cloud-gateway

csrf detection failed 302 forward location problem

Open
#2,383 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Java
Stars
4.9k
Forks
3.5k
Avg merge
20h 57m
Merged PRs (30d)
8

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the HTTPS POST /login flow using gateway-service.yaml and the security-service route in gateway-route, then inspect the 302 Location response. Review the forwarded-header settings, PreserveHostHeader, RewriteLocationResponseHeader, and SecurityConfiguration. Done means the browser remains on HTTPS after the CSRF-related redirect.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring, spring-boot
Domain
api, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.