通过端口/连接器公开/过滤控制器请求映射

时间:2015-10-01 17:38:47

标签: spring spring-mvc spring-boot

我有一个相对简单的Spring Boot应用程序,默认情况下,使用自签名证书通过端口9443上的SSL进行保护,这对于向移动应用程序提供API非常有用。但是,我现在想开发一个带有自己的前端的不安全的Web应用程序,并提供我允许通过SSL的内容的一部分。

这是我到目前为止提出的,除了端口9443之外,它还通过HTTP启用端口8080,后者我已在application.properties中定义:

@SpringBootApplication
@ComponentScan
public class Application extends WebMvcConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        tomcat.addAdditionalTomcatConnectors(createWebsiteConnector());
        return tomcat;
    }

    private Connector createWebsiteConnector() {
        Connector connector = new Connector(TomcatEmbeddedServletContainerFactory.DEFAULT_PROTOCOL);
        connector.setPort(8080);
        return connector;
    }
}

我现在面临的任务是只将端点暴露给8080连接,并将它们全部暴露给9443.显然,后者目前默认工作,但现在8080可以访问9443可以的所有内容。理想情况下,我想控制对" shared"中定义的某些请求映射的访问。两个连接都可以访问的控制器,例如:

@RequestMapping(value = "/public", method = RequestMethod.GET)
public List<String> getPublicInfo() {
    // ...
}

@HTTPSOnly
@RequestMapping(value = "/secured", method = RequestMethod.GET)
public List<String> getSecuredInfo() {
    // ...
}

我认为上面提到的东西实际上并不可行,但是有谁知道我怎么能达到同样的效果呢?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

好吧,我想我实际上已经设法解决了这个问题,但是如果有人认为他们有更好的解决方案,我会接受其他建议:

@SpringBootApplication
@ComponentScan
public class Application extends WebMvcConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        tomcat.addAdditionalTomcatConnectors(createWebsiteConnector());
        return tomcat;
    }

    private Connector createWebsiteConnector() {
        Connector connector = new Connector(TomcatEmbeddedServletContainerFactory.DEFAULT_PROTOCOL);
        connector.setPort(8080);
        return connector;
    }

    private static HashSet<String> uriWhitelist = new HashSet<>(4);
    static {
        // static website content
        uriWhitelist.add("/");
        uriWhitelist.add("/index.html");
        uriWhitelist.add("/logo_48x48.png");

        // public APIs
        uriWhitelist.add("/public");
    }
    private static class PortFilter extends OncePerRequestFilter {

        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            if (request instanceof RequestFacade) {
                RequestFacade requestFacade = (RequestFacade) request;
                if (requestFacade.getServerPort() != 9443 && !uriWhitelist.contains(requestFacade.getRequestURI())) {
                    // only allow unsecured requests to access whitelisted endpoints
                    return;
                }
            }

            filterChain.doFilter(request, response);
        }
    }
    @Bean
    public FilterRegistrationBean portFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        PortFilter filter = new PortFilter();
        filterRegistrationBean.setFilter(filter);
        return filterRegistrationBean;
    }
}