2011-07-24 1 views
5

J'ai un webservice construit en PHP qui utilise UsernameToken comme mécanisme d'authentification. J'ai un code côté client PHP qui peut accéder à ce service web. Maintenant, je dois le faire en Java. Peut-être que tu peux m'aider!Java Webservice Client Nom d'utilisateurToken équivalent à PHP

Ce service est accessible en utilisant le code php suivant:

$password="super_secure_pass"; 
$timestamp=gmdate('Y-m-d\TH:i:s\Z'); 
$nonce=mt_rand(); 
$passdigest=base64_encode(pack('H*',sha1(pack('H*',$nonce).pack('a*',$timestamp).pack('a*',$password)))); 
$nonce=base64_encode(pack('H*',$nonce)) 

Ces valeurs se parsés dans cet en-tête de savon.

<wsse:Security SOAP-ENV:mustUnderstand="0" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
<wsse:UsernameToken> 
    <wsse:Username>'.$username.'</wsse:Username> 
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$passdigest.'</wsse:Password> 
    <wsse:Nonce>'.$nonce.'</wsse:Nonce> 
    <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'.$timestamp.'</wsu:Created> 
    </wsse:UsernameToken> 
</wsse:Security> 

Avec ce code, je peux accéder au service Web sans aucun problème. Maintenant, je dois le faire en Java.

J'ai créé les fichiers neccesary, implémenté un gestionnaire pour ajouter un en-tête de soap avec le nom d'utilisateurToken. Mais quand j'essaie d'accéder au WS, je reçois toujours une erreur "Non Autorisé". Je pense qu'il me manque quelque chose lors de la création de l'entrée passdigest ou nonce.

Voici comment je les calculer:

Random generator = new Random(); 
    String nonceString = String.valueOf(generator.nextInt(999999999)); 
    String createTime=localToGmtTimestamp();//Returns a date with format (SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")) 
    String pass="super_secure_pass"; 
    String tmp = AeSimpleSHA1.SHA1(nonce + createTime + pass); 
    encodedPass = Base64.encodeBytes(tmp.getBytes()); 

Ces valeurs seront utilisées tout en créant l'en-tête de savon:

SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope(); 
    SOAPHeader header = envelope.addHeader(); 
    SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 
    SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse"); 
    SOAPElement username = usernameToken.addChildElement("Username", "wsse"); 
    username.addTextNode(user); 

    SOAPElement password = usernameToken.addChildElement("Password", "wsse"); 
    password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"); 
    password.addTextNode(encodedPass); 

    SOAPElement nonce = 
     usernameToken.addChildElement("Nonce", "wsse"); 
    nonce.addTextNode(Base64.encodeBytes(nonceString.getBytes())); 

    SOAPElement created = usernameToken.addChildElement("Created", "wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); 

    created.addTextNode(creatTime); 

C'est ce que l'en-tête de savon résultant ressemble:

<S:Header> 
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <wsse:UsernameToken> 
      <wsse:Username>myusername</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">ZDM4MjkwNzNlNTc3MjNmMTY4MjgyYWQ1ZjllN2JlZmJmNGY2NDE4MA==</wsse:Password> 
      <wsse:Nonce>NTU5NzA2Mjkw</wsse:Nonce> 
      <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2011-07-24T11:41:55Z</wsu:Created> 
     </wsse:UsernameToken> 
    </wsse:Security> 
</S:Header> 

Est-ce que quelqu'un voit ce que je fais mal?

+0

Merci de poster ce code. Je regardais quelque chose de similaire. – jjwdesign

Répondre

8

J'ai trouvé une solution. Mon problème était que j'ai oublié d'ajouter l'encodage hexadécimal à la valeur de NONCE et à la chaîne concaténée. Voici ma solution, peut-être que certains ont besoin de cela.

Les fonctions pour créer passe etc .:

private String calculatePasswordDigest(String nonce, String created, String password) { 
     String encoded = null; 
     try { 
      String pass = hexEncode(nonce) + created + password; 
      MessageDigest md = MessageDigest.getInstance("SHA1"); 
      md.update(pass.getBytes()); 
      byte[] encodedPassword = md.digest(); 
      encoded = Base64.encodeBytes(encodedPassword); 
     } catch (NoSuchAlgorithmException ex) { 
      Logger.getLogger(HeaderHandler.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     return encoded; 
    } 

    private String hexEncode(String in) { 
     StringBuilder sb = new StringBuilder(""); 
     for (int i = 0; i < (in.length() - 2) + 1; i = i + 2) { 
      int c = Integer.parseInt(in.substring(i, i + 2), 16); 
      char chr = (char) c; 
      sb.append(chr); 
     } 
     return sb.toString(); 
    } 

Code pour construire le message de savon:

String timestamp = HeaderHandler.localToGmtTimestamp(); 
String pass = "password"; 
String user = "username"; 
String nonceString = getNonce(); 


String dig=calculatePasswordDigest(nonceString, timestamp, pass); 


SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope(); 
SOAPHeader header = envelope.addHeader(); 

SOAPElement security = 
header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 


SOAPElement usernameToken = 
security.addChildElement("UsernameToken", "wsse"); 


SOAPElement username = 
usernameToken.addChildElement("Username", "wsse"); 
username.addTextNode(user); 

SOAPElement password = 
usernameToken.addChildElement("Password", "wsse"); 
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"); 
password.addTextNode(dig); 

SOAPElement nonce = 
usernameToken.addChildElement("Nonce", "wsse"); 
nonce.addTextNode(Base64.encodeBytes(hexEncode(nonceString).getBytes())); 

SOAPElement created = usernameToken.addChildElement("Created", "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); 
created.addTextNode(timestamp); 
+0

Bonjour, pourriez-vous donner un indice sur ce que fait getNonce()? Deuxième question: Quelle classe Base64 utilisez-vous? Mine (de Apache.commons) n'a pas la fonction encodeBytes(). Meilleures salutations –