如何在不将应用程序暴露在其他地方的情况下将服务器端Shiny应用程序嵌入到JSP页面中 [英] How can I embed a server-side Shiny app into a JSP page without exposing the app elsewhere

查看:83
本文介绍了如何在不将应用程序暴露在其他地方的情况下将服务器端Shiny应用程序嵌入到JSP页面中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Shiny app that I want to embed into a page of my Java 8 webserver that is hosted on Amazon AWS. (Note: I say "embed" because most pages in the webserver share a common sidebar & footer - this is applied automatically to most views, such that the .jsp files only have to provide html for the real substance of the page).

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

The Shiny app listens on 3305 and the webserver hosts to :8080 on localhost ([server ip]/subject/index.html works fine to get webpages via other machines).

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

Embedding the Shiny app works fine for localhost via a shiny.jsp containing <iframe src="http://localhost:3305">, but when viewed from another machine, the page looks for a shiny server only on that other machine, when it should be looking on the host machine. Leaving off the "http://" results in the Shiny app never getting a request and the page staying blank, and exchanging "localhost" with "127.0.0.1" results in no noticeable changes.

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

The server uses Spring, JSTL and Apache Tomcat 7.0 .

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

I cannot simply port forward the Shiny app to make it visible outside the server, because the app displays confidential information. In a .jsp, this is not a concern, as the iframe can be wrapped in a <security:authorize> tag (the website requires login to access any pages in the first place).

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

The question is, what is the simplest way to embed the Shiny app into a .jsp page such that it remains interactive for the user but is secure (cannot be directly accessed with no authorization from outside the server) and requires no additional logins?

推荐答案

spring mvc rest服务重定向/转发/代理,控制器镜像了Shiny应用,因此我们保留了访问控制:

A la spring mvc rest service redirect / forward / proxy, a Controller mirrors the Shiny app, so that we retain access control:

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视图中,

This handles the Shiny page's HTML and all of its resources. In a JSP view,

<iframe src="shiny-proxy/">

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

Now we just need to handle the ws://[shiny url]/websocket/ request.

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

In web.xml, prevent the webserver from handling it via:

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

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

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

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

所以...原来很简单.

so... turned out to be quite simple.

这篇关于如何在不将应用程序暴露在其他地方的情况下将服务器端Shiny应用程序嵌入到JSP页面中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆