Override the ChannelProcessingFilter with Spring Security 3.0.5 does not work

后端 未结 3 859
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-06 03:17

The default behavior of the Channel Processors is to do a sendRedirect (which is redirect temporary with 302 code). I need to change this behavior so that a permanent (301) redi

3条回答
  •  北海茫月
    2021-02-06 03:41

    I think it's better to write a redirect strategy:

    @Component
    public class PermanentRedirectStrategy implements RedirectStrategy {
        private boolean contextRelative;
    
        @Override
        public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException {
            response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
            response.setHeader("Location", response.encodeRedirectURL(calculateRedirectUrl(request.getContextPath(), url)));
        }
    
        /**
         * Unfortunately DefaultRedirectStrategy.calculateRedirectUrl is private
         * If this weren't the case, we could extend this class from DefaultRedirectStrategy
         * to use its method directly without copying it
         */
        private String calculateRedirectUrl(String contextPath, String url) {
            if (!UrlUtils.isAbsoluteUrl(url)) {
                if (contextRelative) {
                    return url;
                } else {
                    return contextPath + url;
                }
            }
    
            // Full URL, including http(s)://
    
            if (!contextRelative) {
                return url;
            }
    
            // Calculate the relative URL from the fully qualified URL, minus the last
            // occurence of the scheme and base context
            url = url.substring(url.lastIndexOf("://") + 3); // strip off scheme
            url = url.substring(url.indexOf(contextPath) + contextPath.length());
    
            if (url.length() > 1 && url.charAt(0) == '/') {
                url = url.substring(1);
            }
    
            return url;
        }
    }
    

    and then setting it to the existing entry point:

    @Component
    public class ChannelProcessorsPostProcessor implements BeanPostProcessor {
        @Autowired
        private RedirectStrategy permanentRedirectStrategy;
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            ChannelEntryPoint entryPoint = null;
    
            if (bean instanceof SecureChannelProcessor) {
                entryPoint = ((SecureChannelProcessor) bean).getEntryPoint();
            } else if (bean instanceof InsecureChannelProcessor) {
                entryPoint = ((InsecureChannelProcessor) bean).getEntryPoint();
            }
    
            if (entryPoint != null && AbstractRetryEntryPoint.class.isAssignableFrom(entryPoint.getClass())) {
                ((AbstractRetryEntryPoint) entryPoint).setRedirectStrategy(permanentRedirectStrategy);
            }
    
            return bean;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    

提交回复
热议问题