简体   繁体   English

基于 Netsuite 令牌的 API 调用中的模糊身份验证

[英]Ambiguous Authentication in Netsuite Token Based API call

I am trying to make SOAP calls to the Netsuite API using Token Based Authentication.我正在尝试使用基于令牌的身份验证对 Netsuite API 进行 SOAP 调用。 I have a C# client that is generated from WDSL and it is sending the following request (with the secrets replaced).我有一个从 WDSL 生成的 C# 客户端,它正在发送以下请求(替换了秘密)。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:messages_2016_2.platform.webservices.netsuite.com" xmlns:urn1="urn:core_2016_2.platform.webservices.netsuite.com">
   <soapenv:Header>
      <urn:partnerInfo>
         <urn:partnerId>[MyAccountId]</urn:partnerId>
      </urn:partnerInfo>
      <urn:applicationInfo>
         <urn:applicationId>[MyApplicationId]</urn:applicationId>
      </urn:applicationInfo>
      <urn:tokenPassport>
         <urn1:account>[MyAccountId]</urn1:account>
         <urn1:consumerKey>[MyConsumerKey]</urn1:consumerKey>
         <urn1:token>[MyTokenId]</urn1:token>
         <urn1:nonce>1574515852</urn1:nonce>
         <urn1:timestamp>1499135589</urn1:timestamp>
         <urn1:signature algorithm="HMAC-SHA1">Ll8DbLvTWsBh/G7UtenErR03OrM=</urn1:signature>
      </urn:tokenPassport>
   </soapenv:Header>
   <soapenv:Body>
      <urn:getDataCenterUrls>
         <urn:account>[MyAccountId]</urn:account>
      </urn:getDataCenterUrls>
   </soapenv:Body>
</soapenv:Envelope>

I am getting the following response我收到以下回复

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <soapenv:Fault>
         <faultcode>soapenv:Server.userException</faultcode>
         <faultstring>Ambiguous authentication</faultstring>
         <detail>
            <platformFaults:invalidCredentialsFault xmlns:platformFaults="urn:faults_2016_2.platform.webservices.netsuite.com">
               <platformFaults:code>USER_ERROR</platformFaults:code>
               <platformFaults:message>Ambiguous authentication</platformFaults:message>
            </platformFaults:invalidCredentialsFault>
            <ns1:hostname xmlns:ns1="http://xml.apache.org/axis/">partners-java20004.sea.netledger.com</ns1:hostname>
         </detail>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

I have tried lots of different ways of generating the signature, nonce and timestamp.我尝试了很多不同的方法来生成签名、随机数和时间戳。 Currently I have the following:目前我有以下几点:

private string computeNonce()
{
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] data = new byte[20];
    rng.GetBytes(data);
    int value = Math.Abs(BitConverter.ToInt32(data, 0));
    return value.ToString();
}

private long computeTimestamp()
{
    return ((long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}

private TokenPassportSignature computeSignature(string accountId, string consumerKey, string consumerSecret, string tokenId, string tokenSecret, string nonce, long timestamp)
{
    string baseString = accountId + "&" + consumerKey + "&" + tokenId + "&" + nonce + "&" + timestamp;
    string key = consumerSecret + "&" + tokenSecret;
    string signature = "";
    var encoding = new System.Text.ASCIIEncoding();
    byte[] keyBytes = encoding.GetBytes(key);
    byte[] baseStringBytes = encoding.GetBytes(baseString);
    using (var hmacSha1 = new HMACSHA1(keyBytes))
    {
        byte[] hashBaseString = hmacSha1.ComputeHash(baseStringBytes);
        signature = Convert.ToBase64String(hashBaseString);
    }
    TokenPassportSignature sign = new TokenPassportSignature();
    sign.algorithm = "HMAC-SHA1";
    sign.Value = signature;
    return sign;
}

Does anyone have any ideas?有没有人有任何想法? Thanks!谢谢!

I was also struggling with this unhelpful error after switching to TBA.切换到 TBA 后,我也在为这个无益的错误而苦苦挣扎。 Turns out I was still sending the ApplicationInfo property along with the new Consumer Key and Consumer Secret .结果我仍然在发送ApplicationInfo属性以及新的Consumer KeyConsumer Secret

I found this on NetSuite's "SuiteAnswers" site and wanted to quote it here for anyone else still having this problem.我在 NetSuite 的“SuiteAnswers”网站上找到了这个,并想在此引用它以供其他仍然遇到此问题的人使用。

Ambiguous Authentication Errors不明确的身份验证错误

When you use token-based authentication (TBA) in web services, an ambiguous authentication error response is returned if you use another authentication mechanism together with the TBA header.在 Web 服务中使用基于令牌的身份验证 (TBA) 时,如果将其他身份验证机制与 TBA 标头一起使用,则会返回不明确的身份验证错误响应。

You receive this error if besides the TBA header, your request contains an Application ID, a passport object with an email address and a password, or a valid JSESSIONID.如果除了 TBA 标头之外,您的请求还包含应用程序 ID、带有电子邮件地址和密码的护照对象或有效的 JSESSIONID,您会收到此错误。

The error occurs in the following cases:在以下情况下会发生错误:

  • If a single web services request contains a combination of the Passport, TokenPassport and SsoPassport complex types.如果单个 Web 服务请求包含 Passport、TokenPassport 和 SsoPassport 复杂类型的组合。

  • If a single web services request contains both the tokenPassport and the ApplicationInfo complex types, and therefore contains the application ID in the SOAP header.如果单个 Web 服务请求同时包含 tokenPassport 和 ApplicationInfo 复杂类型,因此在 SOAP 标头中包含应用程序 ID。

Source: Token-Based Authentication Errors in Web Services来源: Web 服务中基于令牌的身份验证错误

The getDataCenter calls don't need the passport. getDataCenter 调用不需要通行证。 I just had the same issue with the mapSso function.我只是在 mapSso 函数上遇到了同样的问题。 It looks like the 2017.1 release made them stricter on not accepting the passport看起来 2017.1 版本使他们更严格地不接受护照

I know this is an old question, but I struggled with the same issue, and found a working solution.我知道这是一个老问题,但我遇到了同样的问题,并找到了一个可行的解决方案。

private static void CreateTokenPassport()
{
    // Initialize the netsuite web service proxy.
    _netSuiteService = new NetSuiteService();

    // A valid Token passport signature consists of the following:
    // Create a base string.
    //     The base string is variable created from concatenating a series of values specific to the request.Use an ampersand as a delimiter between values.
    //     The values should be arranged in the following sequence:
    // NetSuite account ID
    // Consumer key
    // Token
    // Nonce(a unique, randomly generated alphanumeric string, with a minimum of six characters and maximum of 64)
    // Timestamp
    // See: https://system.na1.netsuite.com/app/help/helpcenter.nl?fid=section_4395630653.html#bridgehead_4398049137

    string consumerSecret = "";
    string tokenSecret = "";
    string accountId = "";
    string consumerKey = "";
    string tokenId = "";
    string nonce = ComputeNonce();
    long timestamp = ComputeTimestamp();

    string baseString = string.Format("{0}&{1}&{2}&{3}&{4}", accountId, consumerKey, tokenId, nonce, timestamp);
    string secretKey = string.Format("{0}&{1}", consumerSecret, tokenSecret);

    // Initialize the keyed hash object using the secret key as the key
    HMACSHA256 hashObject = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey));

    // Computes the signature by hashing the data with the secret key as the key
    byte[] signature = hashObject.ComputeHash(Encoding.UTF8.GetBytes(baseString));

    // Base 64 Encode
    string encodedSignature = Convert.ToBase64String(signature);

    TokenPassport tokenPassport = new TokenPassport
    {
        signature = new TokenPassportSignature
        {
            Value = encodedSignature,
            algorithm = "HMAC_SHA256"
        },
        account = accountId,
        consumerKey = consumerKey,
        token = tokenId,
        nonce = nonce,
        timestamp = timestamp
    };

    _netSuiteService = new NetSuiteService
    {
        tokenPassport = tokenPassport
    };
}

Utility Methods:实用方法:

private static string ComputeNonce()
{
    return Guid.NewGuid().ToString("N");
}

private static long ComputeTimestamp()
{
    return ((long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}

我不得不修改 XML 并删除 tokenpassport(account,comsumer key,token,nonce,timestamp) 标签并且它起作用了。

I don't know how it's done in C# with HMAC-SHA1 but in Javascript with CryptoJS HMAC-SHA256 you first sign the string and then encode it in Base64:我不知道它是如何在 C# 中使用 HMAC-SHA1 完成的,但是在使用 CryptoJS HMAC-SHA256 的 Javascript 中,您首先对字符串进行签名,然后在 Base64 中对其进行编码:

var baseString = ACCOUNT_ID + "&" + NETSUITE_CONSUMER_KEY + "&" + NETSUITE_TOKEN_ID + "&" + NONCE + "&" + TIMESTAMP;
var key = NETSUITE_CONSUMER_SECRET + '&' + NETSUITE_TOKEN_SECRET;
var HMAC256_Sig = cryptoJS.HmacSHA256(baseString, key);
var HMAC256_Sig_Base64 = cryptoJS.enc.Base64.stringify(HMAC256_Sig);

Then you output it like:然后你输出它:

'<platformCore:signature algorithm = "HMAC_SHA256">' + HMAC256_Sig_Base64 + '</platformCore:signature>'

Remove the passport.取出护照。 Sadly, NetSuite fails if you have this in the code when using Token Auth.遗憾的是,如果您在使用令牌身份验证时在代码中包含此内容,则 NetSuite 会失败。 :/ :/

As per Netsuite SuiteTalk SOAP API document:根据 Netsuite SuiteTalk SOAP API 文档:

Ambiguous Authentication Errors When you use token-based authentication (TBA) in SOAP web services, an ambiguous authentication error response is returned if you use another authentication mechanism together with the TBA header.不明确的身份验证错误 在 SOAP Web 服务中使用基于令牌的身份验证 (TBA) 时,如果您将其他身份验证机制与 TBA 标头一起使用,则会返回不明确的身份验证错误响应。 You receive this error if besides the TBA header, your request contains an Application ID, a passport object with an email address and a password, or a valid JSESSIONID.如果除了 TBA 标头之外,您的请求还包含应用程序 ID、带有电子邮件地址和密码的护照对象或有效的 JSESSIONID,您会收到此错误。 The error occurs in the following cases:在以下情况下会发生错误:

■ If a single SOAP web services request contains a combination of the Passport, TokenPassport and SsoPassport complex types. ■ 如果单个 SOAP Web 服务请求包含 Passport、TokenPassport 和 SsoPassport 复杂类型的组合。

■ If a single SOAP web services request contains both the tokenPassport and the ApplicationInfo complex types, and therefore contains the application ID in the SOAP header. ■ 如果单个 SOAP Web 服务请求同时包含 tokenPassport 和 ApplicationInfo 复杂类型,因此在 SOAP 标头中包含应用程序 ID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM