嗨,这是我的示例项目:示例项目
1-主要应用程序(DemoApplication.java):
@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}
2-配置文件(AppConfig.java):
@Configurationpublic class AppConfig {@Autowiredprivate ServletWebServerApplicationContext server;private static FilterConfig filterConfig = new FilterConfig();@PostConstructvoid init() { //setting default port config filterConfig.addNewPortConfig(8080, "/admin");}@Bean@Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)public FilterConfig createFilterConfig() { return filterConfig;}public void addPort(String schema, String domain, int port, boolean secure) { TomcatWebServer ts = (TomcatWebServer) server.getWebServer(); synchronized (this) { ts.getTomcat().setConnector(createConnector(schema, domain, port, secure)); }}public void addContextAllowed(FilterConfig filterConfig, int port, String context) { filterConfig.addNewPortConfig(port, context);} public void removePort(int port) { TomcatWebServer ts = (TomcatWebServer) server.getWebServer(); Service service = ts.getTomcat().getService(); synchronized (this) { Connector[] findConnectors = service.findConnectors(); for (Connector connector : findConnectors) { if (connector.getPort() == port) { try { connector.stop(); connector.destroy(); filterConfig.removePortConfig(port); } catch (LifecycleException e) { e.printStackTrace(); } } } }}private Connector createConnector(String schema, String domain, int port, boolean secure) { Connector conn = new Connector("org.apache.coyote.http11.Http11NioProtocol"); conn.setScheme(schema); conn.setPort(port); conn.setSecure(true); conn.setDomain(domain); if (secure) { // config secure port... } return conn;}}
3-过滤器(NewPortFilter.java):
public class NewPortFilter {@Bean(name = "restrictFilter")public FilterRegistrationBean<Filter> retstrictFilter(FilterConfig filterConfig) { Filter filter = new oncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // get allowed url contexts Set<String> config = filterConfig.getConfig().get(request.getLocalPort()); if (config == null || config.isEmpty()) { response.sendError(403); } boolean accepted = false; for (String value : config) { if (request.getPathInfo().startsWith(value)) { accepted = true; break; } } if (accepted) { filterChain.doFilter(request, response); } else { response.sendError(403); } } }; FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<Filter>(); filterRegistrationBean.setFilter(filter); filterRegistrationBean.setOrder(-100); filterRegistrationBean.setName("restrictFilter"); return filterRegistrationBean;}}
4-过滤器配置(FilterConfig.java):
public class FilterConfig { private Map<Integer, Set<String>> acceptedContextsByPort = new ConcurrentHashMap<>(); public void addNewPortConfig(int port, String allowedContextUrl) { if(port > 0 && allowedContextUrl != null) { Set<String> set = acceptedContextsByPort.get(port); if (set == null) { set = new HashSet<>(); } set = new HashSet<>(set); set.add(allowedContextUrl); acceptedContextsByPort.put(port, set); } } public void removePortConfig(int port) { if(port > 0) { acceptedContextsByPort.remove(port); } } public Map<Integer, Set<String>> getConfig(){ return acceptedContextsByPort; }}
5-控制器(TestController.java):
@RestControllerpublic class TestController {@AutowiredAppConfig config;@AutowiredFilterConfig filterConfig;@GetMapping("/admin/hello")String test() { return "hello test";}@GetMapping("/alternative/hello")String test2() { return "hello test 2";}@GetMapping("/admin/addNewPort")ResponseEntity<String> createNewPort(@RequestParam Integer port, @RequestParam String context) { if (port == null || port < 1) { return new ResponseEntity<>("Invalid Port" + port, HttpStatus.BAD_REQUEST); } config.addPort("http", "localhost", port, false); if (context != null && context.length() > 0) { config.addContextAllowed(filterConfig, port, context); } return new ResponseEntity<>("Added port:" + port, HttpStatus.OK);}@GetMapping("/admin/removePort")ResponseEntity<String> removePort(@RequestParam Integer port) { if (port == null || port < 1) { return new ResponseEntity<>("Invalid Port" + port, HttpStatus.BAD_REQUEST); } config.removePort(port); return new ResponseEntity<>("Removed port:" + port, HttpStatus.OK); }}
如何测试呢?
在浏览器中:
1-尝试:
http:// localhost:8080 / admin / hello
预期响应 :你好测试
2-尝试:
http:// localhost:8080 / admin / addNewPort?port = 9090&context =
alternative
预期响应 :已添加端口:9090
3-尝试:
http:// localhost:9090 / alternative /
hello
预期响应 :你好测试2
4-尝试预期的错误:
http:// localhost:9090 / alternative / addNewPort?port = 8181&context =
alternative
预期响应(允许使用上下文[替代],但端点未为此控制器在控制器中注册) :Whitelabel错误页面…
http:// localhost:9090 / any / hello
预期的响应(不允许上下文[任何]) :Whitelabel错误页面…
http:// localhost:8888 / any / hello
预期的响应(无效的端口号) :ERR_CONNECTION_REFUSED
http:// localhost:8080 /你好
预期的响应(不允许上下文[/ hello]) :Whitelabel错误页面…
5-尝试删除端口:
http:// localhost:8080 / admin / removePort?port =
9090
6-检查已移除的端口:
http:// localhost:9090 / alternative /
hello
预期响应(端口关闭) :ERR_CONNECTION_REFUSED
希望对您有所帮助。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)