8

我们在 Tomcat6 上启用了基本身份验证。用户在浏览器中进行身份验证,然后启动 JNLP 以在 Java Web Start 中启动应用程序。在启动时,java web start 尝试从服务器下载 jar 文件,但它没有使用已经通过浏览器身份验证的同一会话。基于论坛,我尝试使用 sid 属性在 JNLP 中传递会话 ID,并附加在 URL 中。环境受到限制,因此每个请求都需要经过身份验证,我们不能说排除对未经过身份验证的 jar 文件的请求。下面是我创建 JNLP 文件的 JSP,任何人都可以帮助我们如何继续相同的会话来下载已经通过浏览器身份验证的 jar。

<% response.setContentType("application/x-java-jnlp-file"); %>
<%= "<?xml version=\"1.0\" encoding=\"utf-8\"?>" %>
<!-- JNLP File for SimpleTableDemo -->
<%
String baseURL = request.getRequestURL().toString().replace(request.getRequestURI(), request.getContextPath());
%>
<jnlp codebase="<%=baseURL%>">

    <information>
        <title>Simple Table Demo Application</title>
        <vendor>Try</vendor>
        <description>SimpleTableDemo</description>
        <description kind="short">An application that demonstrates a simple table.</description>
    </information>

    <resources>
        <j2se version="1.6+" />
        <property name="sid" value="<%=request.getSession().getId()%>" />
        <property name="serviceHost" value="<%=request.getServerName()%>"/>
        <property name="servicePort" value="<%=request.getServerPort()%>"/> 
        <jar href="AuthenticateJNLPJars.jar;JSESSIONID=<%=request.getSession().getId()%>" />
    </resources>

    <application-desc main-class="SimpleTableDemo" >
    </application-desc>
</jnlp>
4

4 回答 4

3

我现在有(一些)答案....

我意识到这个问题已经有一年的历史了,但由于它是谷歌搜索这个问题时的第一个结果,我认为完成它是个好主意。

您提供的 jnlp 代码存在一个问题,但首先,您必须检查将 cookie 添加到 url 是否真的有效.....这取决于您的应用程序部署配置。

我不知道它在 Tomcat 上如何...我正在使用 weblogic,在其中你必须在 weblogic.xml 中检查以下属性

 <session-descriptor>
      <url-rewriting-enabled>true</url-rewriting-enabled>
 </session-descriptor>

这意味着,如果可用,weblogic 将从 URL 获取会话 id(使用与代码中相同的格式)

如果它是假的,那么这个解决方案将不起作用,你将不得不在每个请求中发送一个带有会话 id 的 cookie ......如果你找到了一种方法,请回复......它会对我有所帮助很多。

现在,如果 url-rewriting-enable 为真,那么一旦您在脚本中解决了以下问题,这种方法就会起作用。

问题是,一旦 java web start 从浏览器获取 jnlp,它将再次从服务器下载它,因此您必须确保将会话 ID 也添加到该请求中。你可以通过像这样修改初始标签来做到这一点:

<jnlp spec="1.0+" codebase="<%=baseURL%>" href="<%=NAME_OF_JNLP%>;JSESSIONID=<%=SESSION_ID%>"> 

就是这样,代码应该可以工作......

顺便说一句,您添加的属性:

<property name="sid" value="<%=request.getSession().getId()%>" />
<property name="serviceHost" value="<%=request.getServerName()%>"/>
<property name="servicePort" value="<%=request.getServerPort()%>"/> 

与此无关,您可以删除它们,代码仍然有效。

于 2014-09-26T13:08:17.560 回答
2

(我没有足够的权限添加评论,所以我把它作为一个单独的答案。)

阿尔戈德写道:

问题是,一旦 java web start 从浏览器获取 jnlp,它将再次从服务器下载它,因此您必须确保将会话 ID 也添加到该请求中。你可以通过像这样修改初始标签来做到这一点:

<jnlp spec="1.0+" codebase="<%=baseURL%>" href="<%=NAME_OF_JNLP%>;JSESSIONID=<%=SESSION_ID%>">

Argod,当您向jnlp元素添加href属性时,您实际上使 JWS 再次从服务器下载 jnlp 文件。

查看非官方 Java Web Start/JNLP 常见问题解答。这是它所说的:

一个技巧是确保不要在 servlet 发送回 Web Start 的 JNLP 文件中包含 href 属性。这将告诉 Web Start 禁用对 JNLP 文件的更新检查,并且 Web Start 不会将每个新的 JNLP 文件视为应用程序更新 - 只有更新的 jar 文件会。

我刚刚在本地检查过这个。使用href属性,jnlp 文件实际上被下载了 3 次,而 jar 文件被下载了一次。查看我的 Tomcat 日志:

127.0.0.1 ... "GET /my-servlet/jws/myjws.jnlp;JSESSIONID=58080491243456B6A653682FA0A3A738 HTTP/1.1" 200 741
127.0.0.1 ... "GET /my-servlet/jws/myjws.jnlp;JSESSIONID=58080491243456B6A653682FA0A3A738 HTTP/1.1" 200 741
127.0.0.1 ... "GET /my-servlet/jws/myjws.jnlp;JSESSIONID=342082FEA657D765699EADAF5486E9A7 HTTP/1.1" 200 741
127.0.0.1 ... "GET /my-servlet/jws/myjws.jar;JSESSIONID=342082FEA657D765699EADAF5486E9A7 HTTP/1.1" 200 7555

注意最后是如何分配新的 JSESSIONID 的,这很糟糕。另一方面,没有href属性,jnlp 文件被下载一次,jar 文件被下载一次,并且 JSESSIONID 被保留:

127.0.0.1 ... "GET /my-servlet/jws/myjws.jnlp;JSESSIONID=58080491243456B6A653682FA0A3A738 HTTP/1.1" 200 672
127.0.0.1 ... "GET /my-servlet/jws/myjws.jar;JSESSIONID=58080491243456B6A653682FA0A3A738 HTTP/1.1" 200 7555

另一个有趣的地方是,像“sid”、“serviceHost”、“servicePort”(如使用的 OP)这样的 prorerty 名称将被 JWS 拒绝。

<property name="sid" value="<%=request.getSession().getId()%>" />
<property name="serviceHost" value="<%=request.getServerName()%>"/>
<property name="servicePort" value="<%=request.getServerPort()%>"/>

再次,查看Unofficial Java Web Start/JNLP FAQ。这是它所说的:

如果属性为“受信任”,则只能在 XML 启动文件中为不受信任/未签名的应用程序设置属性。当前受信任的属性包括:

  • javaws.*
  • jnlp.*
  • javax.swing.defaultlf
  • sun.java2d.noddraw

换句话说,如果您想将自己的属性传递给您的应用程序,请使用 javaws 作为前缀,例如,使用 javaws.myproperty 而不是 myproperty。

这同样适用于受信任/签名的 JWS 应用程序。

于 2016-02-02T10:42:39.583 回答
1

因为您使用 JSP 创建 JNPL,所以您可以将带有一些安全令牌或会话 ID 的参数传递给您的小程序,然后您的小程序必须在从服务器请求信息时传递该值。

检查这个: 动态生成 JNLP

于 2013-05-01T09:01:01.250 回答
0

你真的很接近了!但是你的安全层需要更多的组件。

关键是 baseURL 变量,创建一个指向 servlet 的 URL,而不是响应 applet 所需的文件,并在其上附加安全令牌或票证。像这样:

/codebaseServlet/ABC123123

codebaseServlet提取并验证安全令牌并使用请求的文件进行响应。现在可以根据需要自由实施您的安全性。您可以使安全令牌在一段时间内有效,或者在用户会话存在时验证请求即将到来的 IP 表单等。

检查: http ://docs.oracle.com/javase/6/docs/technotes/guides/jweb/applet/codebase_determination.html

于 2013-05-01T19:02:28.100 回答