我正在尝试更新我的集成,以处理NetSuite web服务强制使用令牌身份验证的问题。然而,我被困在以下几个方面:
System.Web.Services.Protocols.SoapException模糊认证
我尝试过各种各样的东西,但没有任何改进。如果我使用预先创建的令牌,或者生成令牌,似乎并不重要。我没有创建一个"Cookie容器“,也没有添加一个标准Passport对象。我尝试过几种不同的方法来生成签名和当前值。我甚至在SHA1和SHA256之间切换了一下,认为这可能会产生不同的效果。我要把我的代码写在这里。希望有人能看出我做错了什么。
FYI,这里有一些组件来自于我在这篇文章中发现的东西:Ambiguous Authentication in Netsuite Token Based API call
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;
}发布于 2018-09-17 23:35:17
结果,问题是在设置应用程序ID的同时也指定了令牌Passport。这样做实际上会与系统产生冲突,因为令牌本身在内部引用了应用程序ID。因此,删除将应用程序ID设置为服务对象的位,然后一切都开始正常工作。
发布于 2018-09-27 08:58:15
尝试使用此代码进行基于令牌的身份验证。
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和令牌秘密。它有一些算法。
https://stackoverflow.com/questions/52372386
复制相似问题