spring 通过Servlet过滤器更新的请求头在到达Sping Boot 中的服务端点时恢复为原始值

ruarlubt  于 2023-08-02  发布在  Spring
关注(0)|答案(1)|浏览(88)

我想用基于URL模式的特定Bearer令牌替换现有的“Authorization”头。我的过滤器看起来像这样:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
public class PortalTokenManipulationFilter implements Filter {

    @Autowired
    TokenGeneneratorUtil tokenGeneneratorUtil;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String headerName = "Authorization";
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        if(httpServletRequest.getRequestURI().contains("/specific")){
           String attorneyPortalToken = tokenGeneneratorUtil.generateToken();
           httpServletRequest = new CustomHeaderRequestWrapper(httpServletRequest, HttpHeaders.AUTHORIZATION, "Bearer " + attorneyPortalToken);
        }
        // Continue the filter chain
        filterChain.doFilter(httpServletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

字符串
还有

public class CustomHeaderRequestWrapper extends HttpServletRequestWrapper {
    
        private final String headerName;
        private final String newValue;
    
        public CustomHeaderRequestWrapper(HttpServletRequest request, String headerName, String newValue) {
            super(request);
            this.headerName = headerName;
            this.newValue = newValue;
        }
    
        @Override
        public String getHeader(String name) {
            if (name.equalsIgnoreCase(headerName)) {
                return newValue;
            }
            return super.getHeader(name);
        }

}


服务端点:

@RestController
        public class PortalResource {
            public ResponseEntity<?> receiver(@Validated @RequestPart("data") CaseDetail caseDetail, 
            @RequestHeader(HttpHeaders.AUTHORIZATION) String token) throws IOException {
           
            log.info("Token : {} ", token);  // I get the old value of the token
            return ResponseEntity.status(HttpStatus.CREATED).body("something");
         }
        }


当我在我的服务端点(上面)中读取令牌的值时,我得到的是令牌的旧值,而不是通过Filter更新的值。

wwwo4jvm

wwwo4jvm1#

我在www.example.com中实现了getHeaders()方法CustomHeaderRequestWrapper.java,如下所示。我认为这个方法是隐式调用的。显式地,除了getHeader()之外,实现此方法还保留了请求头的更新值(Authorization)。

import org.springframework.http.HttpHeaders;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

public class CustomHeaderRequestWrapper extends HttpServletRequestWrapper {

    private final String headerName;
    private final String newValue;

    public CustomHeaderRequestWrapper(HttpServletRequest request, String headerName, String newValue) {
        super(request);
        this.headerName = headerName;
        this.newValue = newValue;
    }

    @Override
    public String getHeader(String name) {
        if (name.equalsIgnoreCase(headerName)) {
            return newValue;
        }
        return super.getHeader(name);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        List<String> headerValues = Collections.list(super.getHeaders(name));
        int index = 0;
        for (String value : headerValues) {
            if (HttpHeaders.AUTHORIZATION.equalsIgnoreCase(name)) {
                headerValues.set(index, newValue);
            }
            index++;
        }
        return Collections.enumeration(headerValues);
    }
}

字符串

相关问题