Аутентификация токена веб-служб консольного приложения NetSuite C #, возвращающая «неоднозначную аутентификацию» - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь обновить свои интеграции, чтобы справиться с принудительным использованием токен-аутентификации для веб-сервисов NetSuite. Тем не менее, я застрял, получив следующее:

[System.Web.Services.Protocols.SoapException] Неоднозначная аутентификация

Я пробовал разные вещи без улучшений. Кажется, не имеет значения, использую ли я токен, созданный заранее, или сгенерированный. Я не создаю «Контейнер cookie» и не добавляю стандартный объект Passport. Я пробовал несколько разных методов для генерации подписи и одноразового значения. Я даже переключился между SHA1 и SHA256, думая, что это может изменить ситуацию. Я собираюсь включить свой код здесь. Надеюсь, кто-нибудь увидит, что я делаю не так.

К вашему сведению, здесь есть некоторые компоненты от попытки того, что я нашел в этом посте: Неоднозначная аутентификация в вызове API Netsuite Token Based

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

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Попробуйте использовать этот код для аутентификации на основе токена

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 также использует идентификатор учетной записи, идентификатор токена и секрет токена. Имеет несколько алгоритмов.

0 голосов
/ 18 сентября 2018

Оказывается, проблема заключалась в установке идентификатора приложения при указании паспорта токена.Это на самом деле создает конфликт с системой, которая не знает, что использовать для аутентификации, поскольку сам токен ссылается на внутренний идентификатор приложения.Итак, удалил бит, где ID приложения был установлен для объекта службы, и все стало работать правильно.

...