【解決】SpringBoot使用Security攔截雙斜槓請求導致重定向過多的問題

問題描述:在上篇文章中,SpringSecurity攔截 // 導致報錯 url 請求不合規範問題通過修改Security源碼已解決,

但是又因爲許多靜態文件也帶有 // 進行請求:test//test.css等,導致重定向次數過多

問題解決:使用攔截器對所有請求進行攔截,對 request 請求中的 url 進行重寫

此處參考 spring security關於URL中包含雙斜槓被權限攔截的處理

添加攔截器配置

import javax.servlet.Filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.stereotype.Component;

@Component("permitAllSecurityConfig")
public class UrlConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

    @Autowired
    private Filter uriFormatFilter;

    @SuppressWarnings({ "rawtypes", "unchecked" })
	@Bean
    public FilterRegistrationBean setFilter() {
        FilterRegistrationBean filterBean = new FilterRegistrationBean();
        filterBean.setFilter(uriFormatFilter);
        filterBean.setName("uriFormatFilter");
        filterBean.addUrlPatterns("/*");
        filterBean.setOrder(-10000);
        return filterBean;
    }
}

攔截器


import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

@Component("uriFormatFilter")
// OncePerRequestFilter,它能夠確保在一次請求中只通過一次filter
public class UriFormatFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {

        String uri = httpServletRequest.getRequestURI();
        String newUri = uri.replace("//","/");
        // 使用HttpServletRequestWrapper重寫Request請求參數
        httpServletRequest = new HttpServletRequestWrapper(httpServletRequest){
            @Override
            public String getRequestURI() {
                return newUri;
            }
        };
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}

與之前寫的一個沒有成功的攔截器進行比較:

 httpRequest.getRequestDispatcher(path).forward(request,response);

之前攔截器是服務器內部跳轉,相當於重新發送了一次請求,我理解爲break,退出當前循環進行下一次循環,而當前攔截器是對當前Request內容進行重寫,

然後使用filterChain.doFilter進入其他攔截器,相當於繼續當前請求的工作,繼續執行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章