java - 使用包含 usernametoken 配置文件和 pwd 摘要的 Web 服务

标签 java web-services jax-ws webservice-client ws-security

伙计们,请帮助我!

我创建了一个 Web 服务,它使用 UserNameToken 配置文件安全性和“摘要”等密码类型。当我尝试使用 SOAP-UI 中的 Web 服务(在 xml 头部发送信息)时,我可以正常使用该 Web 服务,但是当我尝试使用 JAVA 使用该 Web 服务时,服务器不会对用户进行身份验证。

我尝试使用 axis 和 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");
}

最佳答案

WS-Security 标准将密码摘要定义为 Base64 (SHA-1 (nonce + 创建的 + 密码))。

您可以通过对 beforeEncryption 变量的内容进行哈希处理并将结果存储到 encryptedRaw 中,然后将其进行 Base64 编码为 encoded 变量来正确反射(reflect)这一点。到目前为止,一切都很好。但是编码变量没有在任何地方使用。由于某种原因,您计算第二个摘要 base64(sha1("password")) 并将其存储到 senha 变量,该变量稍后用于填充 WSS 密码元素。

完全删除计算第二个摘要的代码并使用编码变量的内容:

从概念上讲,将 pwd.setValue() 更改为:

pwdE.setValue(senha)

致:

pwdE.setValue(encoded)

并确保编码变量将是字符串,而不是字节数组。

此外,您应该考虑使用比对象哈希码更好的nonce值。

关于java - 使用包含 usernametoken 配置文件和 pwd 摘要的 Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10586140/

相关文章:

java - xpath无法获取具有命名空间的节点

java - 如何将此代码片段变形为逻辑取决于索引值的 Java 8?

Javascript 从 Web 服务获取数据

java - 访问 Restful Web 服务时出现 404 错误

java - 使用 JAX-WS 跟踪 XML 请求/响应

java - 如何解决 Jersey 错误 服务器遇到意外情况,无法满足请求

java - ImageJ - 当 ImageStack 中的帧发生更改时触发事件

java - Netbeans 6.9.1 中的 BPEL 组合 Web 服务

java - 如何保护 Web 服务位置的安全?

java - 如何一一运行两个java文件-Eclipse?