2

guy's, pleeaseee help me!!!

I created a web service which use UserNameToken Profile security with Password type like 'digest'. When i try to use the webservice from SOAP-UI (sending the information in the head of the xml) i can consume the webservice normally, but when i'm trying consume this webservice with JAVA the server don't authenticate the user.

I try to use axis and JAX-WS (send the information in the head of the envelop - like SOAP-UI) but the server don't authenticate the user.

Can someone help me?

Here is my code:

public void faz() throws NoSuchAlgorithmException, Exception {

    /////////////////////////////////////////////////////////////
    //get the timestamp, nonce and password in SHA-1 and BASE64//       
    /////////////////////////////////////////////////////////////


    String nonce, timestamp, secret;
    nonce = String.valueOf(this.hashCode());
    BASE64Encoder encoder2 = new BASE64Encoder();
    nonce = encoder2.encode(nonce.getBytes());
    Calendar c = Calendar.getInstance();
    c.setTime(new Date());

    timestamp = DatatypeConverter.printDateTime(c);
    timestamp = timestamp.substring(0, 19);
    timestamp = timestamp+"Z";
    secret = "weblogic1";
    MessageDigest SHA1 = null;
    try {
        SHA1 = MessageDigest.getInstance("SHA1");
    } catch (NoSuchAlgorithmException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    ;

    String beforeEncryption = nonce + timestamp + secret;
try {

        SHA1.reset();
        byte[] toEncrypt = beforeEncryption.getBytes("UTF-8");
        SHA1.update(beforeEncryption.getBytes());
    } catch (UnsupportedEncodingException uee) {
        throw new RuntimeException(uee);
    }

    byte[] encryptedRaw = SHA1.digest();
    byte[] encoded = Base64.encodeBase64(encryptedRaw);
    MessageDigest digest = MessageDigest.getInstance("SHA-1");
    digest.update("password".getBytes());
    BASE64Encoder encoder = new BASE64Encoder();
    String senha = encoder.encode(digest.digest());
    System.err.println(senha);
    ////////////////////////////////////
    //////////END //////////////////////        
    ////////////////////////////////////

    CalculaServiceService ss = new CalculaServiceServiceLocator();

    CalculaService service = ss.getCalculaServicePort();

    String uri = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
    String uriCrea = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"; 

    SOAPHeaderElement securityE = new SOAPHeaderElement(uri, "Security",
            null);
    SOAPHeaderElement tokenE = new SOAPHeaderElement(uri, "UsernameToken",
            null);
    SOAPHeaderElement userE = new SOAPHeaderElement(uri, "Username", null);
    tokenE.setObjectValue(null);


    securityE.setObjectValue(null);


    userE.setValue("username");
    SOAPHeaderElement pwdE = new SOAPHeaderElement(uri, "Password", null);
    pwdE.addAttribute(uri, "Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
    pwdE.setValue(senha);

    SOAPHeaderElement nonceE = new SOAPHeaderElement(uri, "Nonce", null);
    nonceE.addAttribute(uri, "EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
    nonceE.setValue(nonce);

    SOAPHeaderElement createdE = new SOAPHeaderElement(uriCrea, "Created", null);
    createdE.setValue(timestamp);




    tokenE.addChildElement(userE);
    tokenE.addChildElement(pwdE);
    tokenE.addChildElement(nonceE);
    tokenE.addChildElement(createdE);
    securityE.addChildElement(tokenE);
    ((Stub) service).setHeader(securityE);
    service.calcula(13, 10, "somar");
}
Elvis Oliveira
  • 941
  • 2
  • 15
  • 29

1 Answers1

3

WS-Security standard defines the password digest as Base64 ( SHA-1 ( nonce + created + password ) ).

You reflect this correctly by hashing the content of beforeEncryption variable and store the result to encryptedRaw and then base64-encode it to encoded variable. So far so good. But the encoded variable is not used anywhere. For some reason, you compute a second digest base64(sha1("password")) and store it to senha variable that is used later to fill the WSS Password element.

Completely remove the code that computes the second digest and use the content of the encoded variable:

Conceptually, change the pwd.setValue() from:

pwdE.setValue(senha)

To:

pwdE.setValue(encoded)

and make sure that encoded variable will be a String, not a byte array.

Additionally, you should consider to use a better value for nonce than an object hash-code.

Matej
  • 6,004
  • 2
  • 28
  • 27
  • Alright... don't work, now i'm getting this error: Message older than allowed MessageAge. Maybe the server configuration is wrong? I will see it. Any Ideas?? – Elvis Oliveira May 14 '12 at 18:42
  • Lines timestamp = timestamp.substring(0, 19); and timestamp = timestamp+"Z"; stink. Adding the "Z" to the end, you specify that the time value is in UTC time zone. Try to use the timestamp as is if it contains the timezone, or specify GMT TZ when creating calendar object. If the formatted time is in different time zone than UTC, you'll actually get time in the past (if you are ahead), or in the future. You have to make sure you'll use correct time value (within freshness period), otherwise server rejects the authentication attempt as a replay attack. See the UsernameToken Profile spec, p7. – Matej May 15 '12 at 09:04
  • It's solved my problem with the time... thanks a lot.... but i'm getting a problem to authenticate... "Unable to validate identity assertions." i am creating the pwd correct? – Elvis Oliveira May 15 '12 at 12:34
  • I solved all the problem now.... i was passing the wrong nonce... i followed this link (in the stackoverflow...) http://stackoverflow.com/questions/6806586/java-webservice-client-usernametoken-equivalent-to-php and i can use my service now... thank Matej! – Elvis Oliveira May 15 '12 at 14:05