2012-05-14 68 views
2

傢伙,pleeaseee幫我!消費與UserNameToken配置Web服務與PWD消化

我創建了使用UserNameToken配置文件的安全與密碼型像「消化」的Web服務。當我嘗試使用SOAP-UI中的webservice(發送xml頭部中的信息)時,我可以正常使用webservice,但是當我嘗試使用此webservice與JAVA時,服務器不會對用戶進行身份驗證。

我嘗試用軸和JAX-WS(發送在信封的頭信息 - 如SOAP-UI),但服務器不驗證用戶身份。

有人可以幫助我嗎?

這是我的代碼:

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

回答

3

WS安全標準定義了密碼摘要爲Base64(SHA-1(隨機數+創建+密碼))。

您通過散列beforeEncryption變量的內容正確地反映這一點,並將結果存儲至encryptedRaw,然後將它的base64編碼到編碼變量。到現在爲止還挺好。但編碼的變量沒有在任何地方使用。出於某種原因,你計算第二個消化的base64(SHA1(「密碼」)),並將其存儲到senha稍後用於填充WSS密碼元素變量。

完全刪除,其計算所述第二摘要的代碼,並使用所述編碼變量的內容:

從概念上講,從改變pwd.setValue():

pwdE.setValue(senha) 

到:

pwdE.setValue(encoded) 

並確保編碼變量將是一個字符串,而不是一個字節數組。

此外,您應該考慮使用比對象散列碼更好的現成值

+0

好的。謝謝Matej。我會測試這個和在這裏報告.... –

+0

好吧...不工作,現在我得到這個錯誤:比允許的MessageAge更早的消息。也許服務器配置是錯誤的?我會看到它。有任何想法嗎?? –

+0

Lines timestamp = timestamp.substring(0,19); 和時間戳=時間戳+「Z」;臭。將「Z」添加到最後,您指定時間值是UTC時區。如果它包含時區,請嘗試使用時間戳,或者在創建日曆對象時指定GMT TZ。如果格式化的時間與UTC的時區不同,那麼您實際上會獲得過去的時間(如果您未來)或未來。您必須確保您使用正確的時間值(在新鮮時間內),否則服務器拒絕認證嘗試作爲重播攻擊。請參閱UsernameToken配置文件規範,第7頁。 – Matej