Развертывание Java-апплета с разрешением безопасности в HTML - PullRequest
1 голос
/ 18 апреля 2011

Мне очень трудно заставить это работать.

Апплет вставлен на мою веб-страницу и пытается подключиться к сервлету Java здесь .

На некоторых компьютерах он нормально подключается, на других я получаю сообщение об ошибке «не удается подключиться», которое, по моему мнению, вызвано разрешениями безопасности Java.

Пользовательский 1: доступ запрещен (соединение java.net.SocketPermission 184.91.186.5:8080, разрешение)

java.security.AccessControlException: access denied (java.net.SocketPermission 184.91.186.5:8080 connect,resolve)
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkConnect(Unknown Source)
    at sun.plugin2.applet.Applet2SecurityManager.checkConnect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at sun.net.NetworkClient.doConnect(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.<init>(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at Calendar_Algorithm$Con.send_courses_to_server(Calendar_Algorithm.java:789)
    at Calendar_Algorithm$Con.run(Calendar_Algorithm.java:773)
    at Calendar_Algorithm.send_courses_to_server(Calendar_Algorithm.java:761)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$LiveConnectWorker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Я подписал файл jar, но он все еще не решает проблему. Вот как я сгенерировал файл ключа и подписал банку.

keytool -genkey -alias cal -keystore keys  -keypass #### -dname "cn=feldman" -storepass ####

jarsigner -keystore keys -storepass #### -keypass #### -signedjar CalSigned.jar Cal.jar cal

Вот как я встраиваю его в HTML-страницу:

<script src="http://java.com/js/deployJava.js"></script>

    <script>
        var attributes = {code:'Calendar_Algorithm.class',
                      archive:'Cal39.jar',
                      width:150, height:50,
                      id:"ClientApp",
                      name:"ClientApp"
                      } ;
        var parameters = {fontSize:16} ;
        var version = '1.6' ;
        deployJava.runApplet(attributes, parameters, version);
    </script>

Я также попытался сделать файл jnlp, и я даже не смог получить его, чтобы запустить jar, вот содержимое моего файла jnlp:

  <?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.5+" codebase="" href="">
    <security>
        <all-permissions/>
    </security>
    <information>
        <title>Easy Course Selector</title> 
        <vendor>Group Boba</vendor>
        <homepage href="index.html"/>
        <description>Easy Course Selector</description>
        <description kind="short">Easy Course Selector</description>
        <icon href="mouseguard-small-jpg3.jpg"/>

    </information>

    <resources>
        <j2se version="1.5+" href="http://java.sun.com/products/autodl/j2se" />
        <jar href="Cal.jar" main="true" download="eager" />
    </resources>
    <applet-desc name="EasyCourse Applet" main-class="Calendar_Algorithm.class" width="200" height="50">
    </applet-desc>
    <update check="background"/>
</jnlp> 

И код для вставки

<script> 
    var attributes = {id:"ClientApp", name:"ClientApp", code:'Calendar_Algorithm',   width:150, height:50} ; 
    var parameters = {jnlp_href: 'Cal_Info.jnlp'} ; 
    deployJava.runApplet(attributes, parameters, '1.6'); 
</script>

Это журнал ошибок, когда я использую его для подключения к внешнему серверу:

java.security.AccessControlException: access denied (java.net.SocketPermission 184.91.186.5:8080 connect,resolve)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkConnect(Unknown Source)
at sun.plugin2.applet.Applet2SecurityManager.checkConnect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.<init>(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at Calendar_Algorithm$Con.send_courses_to_server(Calendar_Algorithm.java:789)
at Calendar_Algorithm$Con.run(Calendar_Algorithm.java:773)
at Calendar_Algorithm.send_courses_to_server(Calendar_Algorithm.java:761)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$LiveConnectWorker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Любая помощь будет потрясающей.

Также вот код, который вызывает ошибку:

class Con implements PrivilegedExceptionAction<Boolean> {
    private final String text;
    boolean res;
    public Con(String t) {
      text=t;
    }

    public Boolean run() { 
      res=send_courses_to_server();
      return res;
    } 
    public boolean send_courses_to_server(){

        try {
            URL url = new URL(server);

            HttpURLConnection con;
            con=(HttpURLConnection) url.openConnection();
            con.setRequestProperty("Content-type", "text/xml; charset=UTF-8");
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);


            OutputStream out = con.getOutputStream();
            Writer writer = new OutputStreamWriter(out, "UTF-8");
            String xml="";
            writer.write("<Request>\n" +"<Request_Type>Validation_2</Request_Type>\n");
            xml="<Request>\n" +"<Request_Type>Validation_2</Request_Type>\n";



            Scanner in=new Scanner(text);
            while(in.hasNext()){
                String temp=in.nextLine().trim();
                writer.write("<Course>"+temp+"</Course>\n");
                xml=xml+"<Course>"+temp+"</Course>\n";
            }
            writer.write("</Request>\n");
            xml=xml+"</Request>\n";

            writer.flush();
            writer.close();

            InputStream is= con.getInputStream();

            if(con.getContentType().equals("text/xml")){
                status_message= new Scanner(is).nextLine();
                return false;
            }
            else{
                return set_courses(is);
            }

        } catch (Exception e){
            e.printStackTrace();
            status_message= "Custom 1: "+e.getMessage();
            return false;
        }

    }

    private boolean set_courses(InputStream is){
        courses=new Vector<Course>();

        try {
            ObjectInputStream ois=new ObjectInputStream(is);

            Course c;
            while(true){
                try{
                    c=(Course)ois.readObject();
                    courses.add(c);
                }catch(EOFException e){
                    break;
                }
            }
            ois.close();
        } catch (Exception e){
            status_message= "Custom 3 "+e.getMessage();
            return false;
        }
        status_message="Good";
        return true;
    }

}

1 Ответ

2 голосов
/ 19 апреля 2011

Теперь, с помощью трассировки стека, мы можем увидеть причину немного лучше.

...
at Calendar_Algorithm$Con.send_courses_to_server(Calendar_Algorithm.java:789)
at Calendar_Algorithm$Con.run(Calendar_Algorithm.java:773)
at Calendar_Algorithm.send_courses_to_server(Calendar_Algorithm.java:761)
...
at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
...

Похоже, вы используете JavaScript для вызова метода вашего апплета. Метод send_courses_to_server вашего класса CalendarAlgorithm вызывается из JavaScript и напрямую вызывает метод run вашего внутреннего класса Con. Это означает, что ваш код работает с (только) разрешениями внешнего JavaScript, а не с разрешениями вашего апплета.

Класс Con расширяет PrivilegedExceptionAction, но одного этого недостаточно для привилегированного выполнения. Вы также должны обернуть это в вызов AccessController.doPrivileged(...) (здесь укажите ваш Con объект).

Затем метод будет вызываться с привилегиями, предоставленными вашему апплету при подписании. (Конечно, вы должны проверить, что этот вызов является законным и не делает ничего плохого.)

Здесь я полагаю, что ваша подпись работает, я не проверял это, поскольку я обычно работаю с неподписанными апплетами. Кстати, если ваш апплет приходит с того же сервера, на котором включен сервлет, это соединение не должно нуждаться в подписи.

...