package com.westcredit.creditchina.security; import com.westcredit.creditchina.security.filter.ParameterDecryptFilter; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springblade.core.api.crypto.annotation.decrypt.ApiDecrypt; import org.springblade.core.tool.utils.Func; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import javax.servlet.Filter; import javax.servlet.FilterRegistration; import java.util.*; import java.util.stream.Collectors; @AllArgsConstructor @Configuration @Order() @Slf4j public class DecryptFilterConfiguration implements WebMvcConfigurer, ApplicationListener<ApplicationReadyEvent> { private final CaptionTokenProperties properties; @Bean public FilterRegistrationBean<Filter> decryptFilter() { FilterRegistrationBean<Filter> registration = new MyRegistrationBean<>(); registration.setFilter(captionDecryptFilter(properties)); registration.setOrder(Integer.MAX_VALUE); return registration; } @Bean public Filter captionDecryptFilter(CaptionTokenProperties properties) { return new ParameterDecryptFilter(properties); } @Override public void onApplicationEvent(ApplicationReadyEvent event) { ConfigurableApplicationContext context = event.getApplicationContext(); MyRegistrationBean<Filter> decryptFilter = (MyRegistrationBean<Filter>) context.getBean("decryptFilter"); RequestMappingHandlerMapping mapping = context.getBean(RequestMappingHandlerMapping.class); Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods(); Collection<String> urlPatterns = map.entrySet().stream().filter(entry -> { HandlerMethod method = entry.getValue(); ApiDecrypt decrypt = method.getBeanType().getAnnotation(ApiDecrypt.class); if (decrypt == null) { decrypt = method.getMethodAnnotation(ApiDecrypt.class); } return decrypt != null; }).map(entry -> entry.getKey().getPatternsCondition().getPatterns()) .flatMap(Collection::stream) .filter(Func::isNotBlank) .map(url -> url.replaceAll("(?<=\\{)(.+?)(?=})", "*").replaceAll("\\{\\*}", "*")) .collect(Collectors.toList()); decryptFilter.setUrlPatterns(urlPatterns); decryptFilter.afterPropertiesSet(); } private class MyRegistrationBean<T extends Filter> extends FilterRegistrationBean<T> { private FilterRegistration.Dynamic registration; @Override protected void configure(FilterRegistration.Dynamic registration) { this.registration = registration; } public void afterPropertiesSet() { setMatchAfter(false); super.configure(registration); } } }