Domanda

Ho un accumulo webservice in PHP che utilizza UsernameToken come meccanismo di autenticazione. Ho PHP codice lato client in grado di accedere a questo servizio web. Ora ho bisogno di fare questo in Java. Forse mi puoi aiutare!

Questo servizio è accessibile utilizzando il seguente codice PHP:

$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))

Questi valori ottenere analizzato in questa intestazione Soap.

<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>

Con questo codice posso accedere al servizio web senza alcun problema. Ora ho bisogno di fare questo in Java.

Ho creato i file neccesary, implementato un gestore per aggiungere un colpo di testa di sapone con l'UsernameToken. Ma quando provo ad accedere alla WS ottengo sempre un errore "non autorizzato". Penso che mi manca qualcosa durante la creazione della voce di passdigest o nonce.

Ecco come li ho calcolato:

    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()); 

Questi valori saranno utilizzati durante la creazione dell'intestazione sapone:

    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);

Questo è ciò che i risultanti sguardi intestazione SOAP come:

    <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>

Qualcuno vedere quello che sto facendo di sbagliato?

È stato utile?

Soluzione

I found a solution. My problem was that I forgot to add hex encode to the NONCE Value and to the concated string. Here is my solution, maybe some need this.

The functions to create pass 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 to build the soap message:

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top