首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NetSuite C#控制台Ambiguous令牌身份验证返回“模糊身份验证”

NetSuite C#控制台Ambiguous令牌身份验证返回“模糊身份验证”
EN

Stack Overflow用户
提问于 2018-09-17 16:47:24
回答 2查看 1.5K关注 0票数 1

我正在尝试更新我的集成,以处理NetSuite web服务强制使用令牌身份验证的问题。然而,我被困在以下几个方面:

System.Web.Services.Protocols.SoapException模糊认证

我尝试过各种各样的东西,但没有任何改进。如果我使用预先创建的令牌,或者生成令牌,似乎并不重要。我没有创建一个"Cookie容器“,也没有添加一个标准Passport对象。我尝试过几种不同的方法来生成签名和当前值。我甚至在SHA1和SHA256之间切换了一下,认为这可能会产生不同的效果。我要把我的代码写在这里。希望有人能看出我做错了什么。

FYI,这里有一些组件来自于我在这篇文章中发现的东西:Ambiguous Authentication in Netsuite Token Based API call

代码语言:javascript
复制
static void Main(string[] args) {
    NameValueCollection _dataCollection = ConfigurationManager.AppSettings;
    NSCreds crd = new NSCreds(_dataCollection); /// just building a data object to handle credentials and keys
    NSWS ns = new NSWS(crd, _dataCollection["appId"]); // token passport gets built here

    // now to make a call to just get a single file from the File Cabinet

    RecordRef pullFile = new RecordRef();
    pullFile.type = RecordType.file;
    pullFile.typeSpecified = true;
    pullFile.internalId = _dataCollection["fileId"];
    ReadResponse rres = ns.service.get(pullFile); // this line throws the error highlighted above
}

public NSWS(NSCreds c, String appId) {
    CheckConnectionSecurity(); // makes sure connection security is set to TLS 1.2
    _pageSize = 100;
    service = new NetSuiteService();
    service.Timeout = 1000 * 60 * 60 * 2;
    service.tokenPassport = prepareTokenPassport(c);
    ApplicationInfo appInfo = new ApplicationInfo();
    appInfo.applicationId = appId;
    service.applicationInfo = appInfo;
}

public TokenPassport prepareTokenPassport(NSCreds c) {
    long TimeStamp = ComputeTimestamp();
    String nonce = CreateNonce_1();
    NSToken token = null;
    if (String.IsNullOrEmpty(c.tokenId) && String.IsNullOrEmpty(c.tokenSecret)) {
        token = GetToken(c.customerKey, c); // make calls to NetSuite to generate token data and build custom object
    } else {
        token = new NSToken(c.tokenId,c.tokenSecret); // build custom object from apps settings data
    }
    String signature = ComputeSignature(c.account, c.customerKey, c.customerSecret, token.tokenId, token.tokenSecret, nonce, TimeStamp);

    TokenPassport tokenPassport = new TokenPassport();
    tokenPassport.account = c.account;
    tokenPassport.consumerKey = c.customerKey;
    tokenPassport.token = token.tokenId;
    tokenPassport.nonce = nonce;
    tokenPassport.timestamp = TimeStamp;
    TokenPassportSignature signatureElement = new TokenPassportSignature();
    signatureElement.algorithm = "HMAC-SHA1"; // "HMAC-SHA256";
    signatureElement.Value = signature;
    tokenPassport.signature = signatureElement;

    return tokenPassport;
}

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

private String CreateNonce_1() {
    int length = 20;
    String AllowedChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    StringBuilder nonce = new StringBuilder();
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] rnd = new byte[1];

    for (int i = 0; i < length; i++) {
        while (true) {
            rng.GetBytes(rnd);
            char c = (char)rnd[0];
            if (AllowedChars.IndexOf(c) != (-1)) {
                nonce.Append(rnd[0]);
                break;
            }
        }
    }

    return nonce.ToString();
}

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

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

private string ComputeSignature(String account, String cKey, String cSecret, String token, String tokenSecret, String nonce, long timeStamp) {
    String baseString = String.Format("{0}&{1}&{2}&{3}&{4}",account,cKey,token,nonce,timeStamp);
    String key = String.Format("{0}&{1}", cSecret, tokenSecret);

    // previous method for encoding the signature
    // Mac is a custom object found from another post here
    // EncryptionMethods is an enumeration from that same post
    /*
    //using (var secretKey = new SecretKeySpec(GetBytes(key), EncryptionMethods.HMACSHA256))
    using (var secretKey = new SecretKeySpec(GetBytes(key), EncryptionMethods.HMACSHA1))
    using (Mac mac = new Mac(secretKey, baseString)) {
        return mac.AsBase64();
    }
    */

    //HMACSHA256 hashObject = new HMACSHA256(Encoding.UTF8.GetBytes(key));
    HMACSHA1 hashObject = new HMACSHA1(Encoding.UTF8.GetBytes(key));
    byte[] signature = hashObject.ComputeHash(Encoding.UTF8.GetBytes(baseString));
    string encodedSignature = Convert.ToBase64String(signature);

    return encodedSignature;
}
EN

回答 2

Stack Overflow用户

发布于 2018-09-17 23:35:17

结果,问题是在设置应用程序ID的同时也指定了令牌Passport。这样做实际上会与系统产生冲突,因为令牌本身在内部引用了应用程序ID。因此,删除将应用程序ID设置为服务对象的位,然后一切都开始正常工作。

票数 2
EN

Stack Overflow用户

发布于 2018-09-27 08:58:15

尝试使用此代码进行基于令牌的身份验证。

代码语言:javascript
复制
TokenPassport tokenPassport = new TokenPassport();
tokenPassport.account = account; //Account ID
tokenPassport.consumerKey = consumerKey; //Consumer Key
tokenPassport.token = tokenId; // Token ID
tokenPassport.nonce = nonce;   //It is some calculated value with the help of RNGCryptoServiceProvider class.
tokenPassport.timestamp = timestamp;
tokenPassport.signature = signature; // It is TokenPassportSignature  

TokenPassportSignature还使用帐户ID、令牌ID和令牌秘密。它有一些算法。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52372386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档