問題描述:在上篇文章中,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進入其他攔截器,相當於繼續當前請求的工作,繼續執行