【问题标题】:SOAP security in SalesforceSalesforce 中的 SOAP 安全性
【发布时间】:2011-02-16 16:16:50
【问题描述】:

我正在尝试更改当前如下所示的 Web 服务调用标头的 wsdl2apex 代码:
<env:Header>
<Security xmlns="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
<UsernameToken Id="UsernameToken-4">
<Username>test</Username>
<Password>test</Password>
</UsernameToken>
</Security>
</env:Header>

看起来像这样:
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-4" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>Test</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Test</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>

一个问题是我不知道如何更改元素的命名空间(或者即使它们的名称很重要)。第二个问题是将 Type 属性放在 Password 元素上。

任何人都可以提供任何可能有帮助的信息吗?

谢谢

【问题讨论】:

    标签: soap header salesforce ws-security apex-code


    【解决方案1】:

    我遇到了类似的问题。我能够生成以下适用于我的实施的 SOAP 标头:

       <env:Header>
          <Security xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
             <UsernameToken>
                <Username>aaaaaa</Username>
                <Password>xxxxxx</Password>
                <Nonce>MzI3MTUzODg0MjQy</Nonce>
                <wsu:Created>2013-04-23T16:09:00.701Z</wsu:Created>
             </UsernameToken>
          </Security>
       </env:Header>
    

    安全类:

    public class OasisOpenOrgWssSecuritySecext 
    {
    
        // UserToken Class
        public class UsernameToken 
        {
            // Constructor for UsernameToken used to pass in username and password parameters
            public UsernameToken(String username, String password)
            {
                this.Username = username;
                this.Password = password;
                this.Nonce = generateNounce();
                this.Created = generateTimestamp();
            }
    
            public String Username;
            public String Password;
            public String Nonce;
            public String Created;
            private String[] Username_type_info = new String[]{'Username','http://www.w3.org/2001/XMLSchema','string','0','1','false'};
            private String[] Password_type_info = new String[]{'Password','http://www.w3.org/2001/XMLSchema','string','0','1','false'};
            private String[] Nonce_type_info = new String[]{'Nonce','http://www.w3.org/2001/XMLSchema','string','0','1','false'};
            private String[] Created_type_info = new String[]{'wsu:Created','http://www.w3.org/2001/XMLSchema','string','0','1','false'};        
            private String[] apex_schema_type_info = new String[]{'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd','true','false'};
            private String[] field_order_type_info = new String[]{'Username','Password','Nonce','Created'};
    
            // Generate Nounce, random number base64 encoded
            public String generateNounce()
            {
                Long randomLong = Crypto.getRandomLong();
                return EncodingUtil.base64Encode(Blob.valueOf(String.valueOf(randomLong)));
            }
    
            // Generate timestamp in GMT
            public String generateTimestamp()
            {
                return Datetime.now().formatGmt('yyyy-MM-dd\'T\'hh:mm:ss\'Z\'');
            }
        }
    
        // SecurityHeaderType Class
        public class SecurityHeaderType 
        {       
            // Constructor for SecurityHeaderType used to pass in username and password parameters and instantiate the UsernameToken object     
            public SecurityHeaderType(String username, String password)
            {
                this.UsernameToken = new OasisOpenOrgWssSecuritySecext.UsernameToken(username, password);
            }
    
            public String wsuNamespace = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';              
            public OasisOpenOrgWssSecuritySecext.UsernameToken UsernameToken;
            private String[] UsernameToken_type_info = new String[]{'UsernameToken','http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd','UsernameToken','1','1','false'};
            private String[] wsuNamespace_att_info = new String[]{'xmlns:wsu'};               
            private String[] apex_schema_type_info = new String[]{'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd','true','false'};
            private String[] field_order_type_info = new String[]{'UsernameToken'};
        }
    }
    

    将 cmets 之间的行添加到由 wsdl2apex 生成的类中:

    public class XyzWebService {
        public String endpoint_x = 'https://webservice/'
        // ADDITION TO WSDL
        public OasisOpenOrgWssSecuritySecext.SecurityHeaderType Security = new OasisOpenOrgWssSecuritySecext.SecurityHeaderType( 'aaaaaa', 'xxxxxx');
        private String Security_hns = 'Security=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';**                            
        // END ADDITION TO WSDL
        public Map<String,String> inputHttpHeaders_x;
        public Map<String,String> outputHttpHeaders_x;
        public String clientCertName_x;
        public String clientCert_x;
        public String clientCertPasswd_x;
        public Integer timeout_x;
    

    【讨论】:

    • 我试过这个。我确定我使用了正确的用户名和密码。我得到响应:验证消息 faultcode=ns1:SecurityError 时遇到安全错误。这个通用消息并没有真正帮助我。我尝试省略 Nonce 和 Created(我在其他地方找到的提示),但结果相同。有人有其他提示可以帮助我吗?
    • 嗨。你终于明白了吗?
    【解决方案2】:

    我遇到了类似的问题。我手动创建了一个类来创建基本结构。幸运的是,我使用的服务在没有显式设置类型参数的情况下假设或能够确定类型是文本,因此您可能想尝试一下,看看它是否有效。

    对于命名空间,我将它们设置为属性:

    private String[] wsu_att_info = new String[] {'xmlns:wsu'};
    

    这个问题也可能有帮助:What are the parameters for the Salesforce WebServiceCallout.invoke method?

    【讨论】:

    • 我不认为你找到了如何将属性添加到只包含字符串的元素中,对吧?
    • 因为我得到了一些工作,没有,但我确实得到了一个我还没有机会测试的答案:(stackoverflow.com/questions/4413631/…)
    • 我刚刚尝试过实现它,但我似乎无法解决。如果某处有文档会更容易,但如果它确实存在,我找不到它。
    【解决方案3】:

    可能不是每个人都可以,但我们设法通过使用 XSLT 将我们拥有的 SOAP 转换为我们想要的 SOAP 来解决这个问题。

    【讨论】:

    • 我的需求和你的完全一样。您能否提供更多详细信息,说明您是如何实现这一目标的?
    • @HSG 这是 8 年以前的多个工作,所以我恐怕不能太多。我假设我使用 XSLT 将我们拥有的格式映射到我们想要的格式。
    • 别担心,我想我快到了。感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 2015-08-30
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多