web-dev-qa-db-fra.com

Pourquoi mon applet obtient-elle une exception Java.security.AccessControlException: accès refusé (Java.net.SocketPermission ...), et comment puis-je l'éviter?

Nous ne savons absolument pas pourquoi mon client rencontre une Java exception de sécurité dans Safari. Quelqu'un pourrait-il aider?

L'exception se produit de manière fiable dans Safari sur Windows. Cela implique une applet Java. L'exception se produit également avec Firefox et IE8 sur Windows Vista.

Voici les étapes pour reproduire:

  1. Ouvrez Safari sur Windows

  2. Cliquez ici: http://www.cengraving.com/s/item?itemId=CH0

  3. Cliquez sur "Personnaliser" (en bas de l'écran)

  4. Une fois la page "Instant Proof" chargée, cliquez sur "Ajouter au panier".

Trace de pile complète:

Java.security.AccessControlException: access denied (Java.net.SocketPermission www.cengraving.com 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.plugin.security.ActivatorSecurityManager.checkConnect(Unknown Source)
    at Java.net.InetAddress.getAllByName0(Unknown Source)
    at Java.net.InetAddress.getAllByName(Unknown Source)
    at Java.net.InetAddress.getAllByName(Unknown Source)
    at Java.net.InetAddress.getByName(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 com.designapplet.a.f.a(Unknown Source)
    at com.designapplet.ui.c.a(Unknown Source)
    at com.designapplet.ui.c.for(Unknown Source)
    at com.designapplet.ui.DesignApplet.buy(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.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.GeneratedMethodAccessor2.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.plugin.liveconnect.PrivilegedCallMethodAction.run(Unknown Source)
    at Java.security.AccessController.doPrivileged(Native Method)
    at Sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at Java.security.AccessController.doPrivileged(Native Method)
    at Sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
Java.net.MalformedURLException: no protocol: 
    at Java.net.URL.<init>(Unknown Source)
    at Java.net.URL.<init>(Unknown Source)
    at Java.net.URL.<init>(Unknown Source)
    at Sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
    at Sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
    at Sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at Java.security.AccessController.doPrivileged(Native Method)
    at Sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
Java.net.MalformedURLException: no protocol: 
    at Java.net.URL.<init>(Unknown Source)
    at Java.net.URL.<init>(Unknown Source)
    at Java.net.URL.<init>(Unknown Source)
    at Sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
    at Sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
    at Sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at Java.security.AccessController.doPrivileged(Native Method)
    at Sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
17
Crashalot

Merci pour les réponses. Je n'ai pas accordé de prime parce que même si les réponses étaient toutes utiles, aucune n'a résolu le problème.

Finalement, j'ai résolu le problème en transmettant les données de l'applet à la page Web, puis en exécutant un appel AJAX pour communiquer avec le serveur. Pas la solution la plus élégante, certes, mais elle s'est avérée efficace jusqu'à présent.

Essayez-le et laissez-moi savoir si cela fonctionne pour vous.

Merci encore!

2
Crashalot

Vous pouvez remplacer le fichier de stratégie de sécurité par défaut utilisé par SecurityManager.

1) Créez un fichier texte (par exemple, applet.policy)

2) Accordez toutes les autorisations à l'applet

  grant {
   permission Java.security.AllPermission;
  };

3) Exécutez l'applet avec

-J-Djava.security.policy=applet.policy
16
Seb74

j'ai eu le même problème. Et résolu cela en auto-signant l'applet ...

utilisé les étapes suivantes et cela a fonctionné

javac AppletClass.Java
jar cvf AppletClass.jar AppletClass.class
keytool -genkey -validity 3650 -keystore pKeyStore -alias keyName
keytool -selfcert -keystore pKeyStore -alias keyName-validity 3650
jarsigner -keystore pKeyStore AppletClass.jar keyName

il suffit de répondre aux questions qu'il posera et il fera le travail

REMARQUE: j'obtenais l'erreur pour le fichier de lecture/écriture local

9
Varun

J'ai le même problème! JavaScript appelle une méthode publique d'une applet incorporée dans le même document. Cela devrait déclencher que l'applet charge certaines données de "home", de sorte que la connexion doit être ouverte au même domaine à partir duquel l'applet a été chargée - ce qui devrait être autorisé également pour les applets non signées sans autres privilèges.

J'ai également reconnu cette exception de sécurité uniquement avec Safari (5.0.2 pour Windows, JRE 1.6.0_22). La même applet dans IE et FireFox se porte bien.

Je pense aussi que c'est un bug dans le Java Sandbox de Safari.


EDIT: L'utilisation de doPrivileged n'a pas aidé mais j'ai trouvé cette solution de contournement: si vous "découplez" l'appel JavaScript de l'exécution demandée via un événement de minuterie, l'exécution ne sera plus interdite par la restriction de sécurité que Safari met dans le jeu ici. En détail:

  • la méthode appelée à partir de JavaScript crée uniquement un javax.swing.Timer (pour planifier un événement de sorte que la propriété repeat doit être définie sur false). Vous pouvez régler le délai assez court (par exemple 50 ms).
  • L'appel de méthode qui doit être appelé doit être placé dans l'écouteur ActionEvent (actionPerformed) qui est appelé par le temporisateur.

Un problème qui pourrait rendre les choses un peu plus compliquées est que dans le contexte actionPerformed, seules les variables statiques sont accessibles. Si l'appel JavaScript contient des variables, celles-ci doivent être placées par la méthode initialement appelée dans une variable "tampon" statique à partir de laquelle l'événement planifié peut lire la valeur par la suite.

Dans mes tests, seul le javax.swing.Timer a fourni le découplage requis tandis que Java.util.Timer ne pouvait pas être utilisé à cette fin.

4
Hacky

Est-ce une applet? Si c'est le cas, vous devez signer votre applet pour qu'elle accède à une socket, (ce qui semble être ce que vous faites ...)

Voir ici pour plus d'informations:

http://Java.Sun.com/developer/onlineTraining/Programming/JDCBook/signed.html

0
Starkey

Sous Linux, cela fonctionne.

Le bouton Add to cart Exécute la fonction

  function saveLayout() {

    showSaveMsg();
    var status = document.app.buy();
    var loc = "http://www.cengraving.com/s/cart";

    if (status == 'GOOD') {
      window.location = getCartUrl();
    } else {
      showErrorMsg(status);
    }
  } 

Quelques remarques:

  • Est-il normal que la variable locale _ loc soit définie après l'appel de l'application et ne soit pas utilisée de toute façon?

  • De plus, un trycatch peut aider (en Javascript, encapsuler l'appel app.buy()).

  • D'ailleurs, j'ai fait un peu de recherche sur le Net, et certaines personnes - ayant la même erreur mais d'une utilisation différente - signalent un problème de ClassPath. Avez-vous quelque chose de spécifique qui pourrait empêcher l'utilisation du JRE correspondant?

0
Ring Ø

Cela se manifeste comme une exception de sécurité, mais le problème est vraiment une mauvaise URL. Si vous suivez la pile, vous verrez qu'il y a une exception MalformedURLException.

Cela est probablement dû au passage d'un URI quelque part qui attendait une URL. Grâce à l'API LiveConnect dès son apparence. Je suppose qu'il ne trouve pas de nom d'hôte là où l'on est attendu et essaie de se connecter à un hôte par défaut, probablement localhost. C'est interdit par le SecurityManager d'où la SecurityException.

Dans les href, vous pouvez utiliser l'URI (par exemple, HREF = "/ somepath") parce que le navigateur résout cela par rapport à l'URL de la page elle-même pour produire l'URL complète (par exemple, http://example.com/somepath ).

Vous pouvez le faire dans Java en utilisant le [constructeur d'URL approprié] [1].

Mise à jour: Ah, j'ai mal lu; Je pensais que c'était une trace de pile unique.

Il y avait autrefois un bogue où liveconnect pouvait accéder à une jar: url et obtenir une connexion socket arbitraire. Le correctif pourrait provoquer un problème avec l'ouverture des connexions URL à partir du thread liveconnect. Que se passe-t-il si, dans la méthode buy, vous démarrez un thread pour effectuer la connexion?

[1]: http://download.Oracle.com/javase/6/docs/api/Java/net/URL.html#URL (Java.net.URL , Java.lang.String )

0
Devon_C_Miller

Le sandbox JRE essaie d'empêcher les appels de méthode d'origine javascript pour faire des choses nuisibles, mais la seule chose qu'il fait rend la vie des programmeurs plus difficile.

La meilleure solution de contournement que j'ai trouvée est de créer une file d'attente d'événements de modèle de conception de producteur et de consommateur qui implémente un couplage très lâche entre les appels générés par javascript et le "sale boulot".

Ce qui est vraiment nul, c'est qu'un code qui fonctionne bien dans XP ou Win7 peut lever l'exception dans Vista.

0
Hasa