如何在不将应用程序暴露在其他地方的情况下将服务器端Shiny应用程序嵌入到JSP页面中

时间:2018-10-02 02:00:26

标签: html5 spring-mvc iframe spring-security shiny

我有一个Shiny应用程序,我想嵌入到Amazon AWS上托管的Java 8 Web服务器的页面中。 (注意:我说“嵌入”是因为Web服务器中的大多数页面共享一个共同的侧边栏和页脚-这会自动应用于大多数视图,因此.jsp文件只需要为页面的实际内容提供html)。 / p>

Shiny应用程序在3305上进行侦听,并且Web服务器将主机托管到本地主机上的:8080([server ip] /subject/index.html可以很好地通过其他计算机获取网页)。

通过包含<iframe src="http://localhost:3305">的shiny.jsp,将Shiny应用程序嵌入localhost可以正常工作,但是当从另一台计算机上查看时,该页面仅在该计算机上查找该服务器上的光泽服务器。主机。取消使用“ http://”将导致Shiny应用程序永远不会收到请求,并且页面将保持空白,而将“ localhost”与“ 127.0.0.1”交换不会导致任何明显的变化。

服务器使用Spring,JSTL和Apache Tomcat 7.0。

我不能简单地端口转发Shiny应用程序以使其在服务器外部可见,因为该应用程序显示机密信息。在.jsp文件中,这无关紧要,因为iframe可以包装在<security:authorize>标签中(网站要求登录才能访问任何页面)。

问题是,将Shiny应用程序嵌入.jsp页面的最简单方法是什么,以使其对用户保持交互但安全(无法从服务器外部未经授权直接访问),并且不需要其他操作登录吗?

2 个答案:

答案 0 :(得分:0)

您可以从Web服务器公开代理API,以检索Shiny应用程序的内容。然后,您可以使用iframe以代理作为src来显示闪亮的应用程序的内容。

答案 1 :(得分:0)

一个spring mvc rest service redirect / forward / proxy控制器是一个镜像Shiny应用程序,因此我们保留了访问控制:

import java.net.URI;
import java.util.Arrays;    
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;

@Controller
public class ShinyController
{
    private static final RestTemplate restTemplate = new RestTemplate();

    @RequestMapping(path = "/shiny-proxy/**")
    public ResponseEntity<String> mirrorRest(@RequestBody(required = false) String body,
            HttpMethod method, HttpServletRequest request) throws URISyntaxException {
        String path = StringUtils.removeStart(
            request.getRequestURI(), "/project/shiny-proxy");
        URI uri = new URI(request.getScheme(), null, "localhost", 3305,
                          path, request.getQueryString(), null);

        HttpHeaders headers = new HttpHeaders();
        if (path.endsWith(".css.map")) {
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        }
        HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);
        return restTemplate.exchange(uri, method, httpEntity, String.class);
    }
}

这处理Shiny页面的HTML及其所有资源。在JSP视图中,

<iframe src="shiny-proxy/">

现在,我们只需要处理ws:// [shiny url] / websocket /请求。

在web.xml中,阻止Web服务器通过以下方式对其进行处理:

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>/project/shiny-proxy/websocket/</url-pattern>
</servlet-mapping>

然后,在Include conf/extra/httpd-vhosts.conf中启用/opt/bitnami/apache2/conf/httpd.conf

并将httpd-vhosts.conf的内容设置为:

<VirtualHost *:80>
  RewriteEngine on
  RewriteRule /project/shiny-proxy/websocket/(.*) ws://localhost:3305/websocket/$1 [P,L]
</VirtualHost>

所以...原来很简单。