Java TBA访问NetSuite Restlet时的403错误

本周有同学问为啥Java访问NetSuite Restlet时,按照知识会之前的文章分享,会一直报403 INVALID_LOGIN_ATTEMPT错误。

https://nk-community.blog.csdn.net/article/details/131399801icon-default.png?t=N7T8https://nk-community.blog.csdn.net/article/details/131399801原因是之前的文章是基于访问REST Webservice的场景,由于访问Restlet时是有些细微区别的,照搬代码是会报错的。这个区别在于Base String的构建。

通过TBA访问NetSuite的服务时,不同的服务其对Base String的格式要求是有不同的。SOAP Webservice, REST Webservice,Restlet三种各不相同。

区别于REST Webservice的是,Restlet的Base String需要加上deploy和script参数。

下面附上调试通过的Java脚本,请参考。

//访问NetSuite Restlet,请注意Base String中Host的小写格式。
//Rick Mao 2024-1-5import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.net.URLEncoder;
import java.util.*;public class NetSuiteRestletAccess {private static final String NETSUITE_ACCOUNT = "XXX"; //对字母大写private static final String NETSUITE_CONSUMER_KEY = "XXX";private static final String NETSUITE_CONSUMER_SECRET = "XXX";private static final String NETSUITE_TOKEN_ID = "XXX";private static final String NETSUITE_TOKEN_SECRET = "XXX";// Generate the timestamp and nonceprivate static final String timestamp = Long.toString(System.currentTimeMillis() / 1000L);private static final String nonce = UUID.randomUUID().toString();public static void main(String[] args) throws Exception {// Create OkHttpClient with logging interceptor for debuggingHttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(loggingInterceptor).build();// Create the request URLHttpUrl requestUrl = HttpUrl.parse("https://" + NETSUITE_ACCOUNT + ".restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=1795&deploy=1");// Generate the Authorization header valueString authorizationHeader = generateAuthorizationHeader(requestUrl.toString());// Create the requestRequest request = new Request.Builder().url(requestUrl).header("Authorization", authorizationHeader).get().build();// Execute the requesttry (Response response = httpClient.newCall(request).execute()) {// Process the responseString responseBody = response.body().string();System.out.println(responseBody);}}private static String generateAuthorizationHeader(String url) throws Exception {String baseString = baseStringConcat();// Generate the signatureString signature = generateSignature(baseString, NETSUITE_CONSUMER_SECRET, NETSUITE_TOKEN_SECRET);// Construct the Authorization header valueString AuthString = "OAuth " +"realm=\"" + NETSUITE_ACCOUNT + "\"," +"oauth_consumer_key=\"" + NETSUITE_CONSUMER_KEY + "\"," +"oauth_token=\"" + NETSUITE_TOKEN_ID + "\"," +"oauth_signature_method=\"HMAC-SHA256\"," +"oauth_timestamp=\"" + timestamp + "\"," +"oauth_nonce=\"" + nonce + "\"," +"oauth_version=\"1.0\"," +"oauth_signature=\"" + URLEncoder.encode(signature, StandardCharsets.UTF_8) + "\"";return AuthString;}private static String generateSignature(String baseString, String consumerSecret, String tokenSecret) throws NoSuchAlgorithmException, InvalidKeyException {String EMPTY_STRING = "";String CARRIAGE_RETURN = "\r\n";String key = URLEncoder.encode(consumerSecret, StandardCharsets.UTF_8) + "&" + URLEncoder.encode(tokenSecret, StandardCharsets.UTF_8);SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");Mac sha256Hmac = Mac.getInstance("HmacSHA256");sha256Hmac.init(secretKey);byte[] signatureBytes = sha256Hmac.doFinal(baseString.getBytes(StandardCharsets.UTF_8));String resultSignature = new String(java.util.Base64.getEncoder().encode(signatureBytes));return resultSignature.replace(CARRIAGE_RETURN, EMPTY_STRING);}public static String generateSignatureBaseString(String httpMethod, String url, Map<String, String> parameters) throws Exception {StringBuilder baseString = new StringBuilder();// URL-encode the components of the URLString encodedUrl = URLEncoder.encode(url, StandardCharsets.UTF_8);// Sort and encode the parametersMap<String, String> sortedParameters = new HashMap<>(parameters);sortedParameters.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEachOrdered(entry -> {try {String key = URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8);String value = URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8);baseString.append(key).append("=").append(value).append("&");} catch (Exception e) {e.printStackTrace();}});// Remove the trailing '&' characterif (baseString.length() > 0) {baseString.setLength(baseString.length() - 1);}// Construct the signature base stringString signatureBaseString = httpMethod.toUpperCase() + "&" + encodedUrl + "&" + URLEncoder.encode(baseString.toString(), "UTF-8");return signatureBaseString;}private static String baseStringConcat() throws Exception {String httpMethod = "GET";//NETSUITE_ACCOUNT 需要转为小写,否则服务端报InvalidSignature错。String url = "https://"+ NETSUITE_ACCOUNT.toLowerCase() + ".restlets.api.netsuite.com/app/site/hosting/restlet.nl";Map<String, String> parameters = new HashMap<>();parameters.put("deploy", "1"); //Restlet访问专用,deploy id需具实际调整。parameters.put("oauth_consumer_key", NETSUITE_CONSUMER_KEY);parameters.put("oauth_nonce", nonce);parameters.put("oauth_signature_method", "HMAC-SHA256");parameters.put("oauth_timestamp", timestamp);parameters.put("oauth_token", NETSUITE_TOKEN_ID);parameters.put("oauth_version", "1.0");parameters.put("script", "1795");//Restlet访问专用,script id需具实际调整。String signatureBaseString = generateSignatureBaseString(httpMethod, url, parameters);System.out.println(signatureBaseString);return signatureBaseString;}
}

如果有任何关于NetSuite的问题,欢迎来谈。邮箱:service@truston.group

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/323240.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(03)光刻——半导体电路的绘制

01、绘制精细电路的第一步 金属-氧化物半导体场效应晶体管(MOSFET)的革命,让我们可以在相同面积的晶圆上同时制造出更多晶体管。MOSFET体积越小,单个 MOSFET的耗电量就越少,还可以制造出更多的晶体管,让其发挥作用,可谓是一举多得。可见,制造更小的MOSFET成了关键因素…

服务器执行rm命令时自动记录到审计日志中

目的 当在服务器上执行类似于 rm 命令时&#xff0c;自动记录该命令执行的时间&#xff0c;在哪里执行的&#xff0c;删除的什么文件&#xff0c;记录到审计日志中&#xff0c;能够查找到某些文件丢失原因 配置 # 需要root权限&#xff0c;sudo不行&#xff0c;这里假设执行…

mariadb配置慢sql查询

Mariadb和Mysql配置相同 这里配置的事mariadb 修改配置文件 vi /etc/my.cnf.d/server.cnf[mysqld] slow_query_logon slow_query_log_file/data/mysql_data/slow_query_log.log long_query_time2slow_query_logon 开启慢sql查询slow_query_log_file/data/mysql_data/slow_que…

某音关键词搜索商品接口,某音关键词搜索商品列表接口,宝贝详情页接口,某音商品比价接口接入方案

要接入API接口以采集电商平台上的商品数据&#xff0c;可以按照以下步骤进行&#xff1a; 1、找到可用的API接口&#xff1a;首先&#xff0c;需要找到支持查询商品信息的API接口。这些信息通常可以在电商平台的官方文档或开发者门户网站上找到。 2、注册并获取API密钥&#x…

RT-DETR算法优化改进:新颖的Shape IoU结合 Inner-IoU,基于辅助边框的IoU损失的同时关注边界框本身的形状和尺度,小目标实现高效涨点

💡💡💡本文改进:一种新的Shape IoU方法结合 Inner-IoU,基于辅助边框的IoU损失的同时,更加关注边界框本身的形状和尺度来计算损失 💡💡💡对小目标检测涨点明显,在VisDrone2019、PASCAL VOC均有涨点 RT-DETR魔术师专栏介绍: https://blog.csdn.net/m0_6377421…

3D Gaussian Splatting复现

最近3D Gaussian Splatting很火&#xff0c;网上有很多复现过程&#xff0c;大部分都是在Windows上的。Linux上配置环境会方便简单一点&#xff0c;这里记录一下我在Linux上复现的过程。 Windows下的环境配置和编译&#xff0c;建议看这个up主的视频配置&#xff0c;讲解的很细…

ZkSync第一Dex空投交互全教程,Holdstation ZK热点不容错过

2023 年 12 月 8 日&#xff0c;在以太坊基金会的 176 次会议上&#xff0c;开发人员一致同意&#xff0c;如果事情进展顺利&#xff0c;将在 2024 年初定 Goerli 分叉日期&#xff0c;目标是能在 2024 年 1 月激活 Goerli Dencun 测试网&#xff0c;预计能够在 2024 年 3 月~ …

云消息队列 Kafka 版生态谈第一期:无代码转储能力介绍

作者&#xff1a;娜米 云消息队列 Kafka 版为什么需要做无代码转储 云消息队列 Kafka 版本身是一个分布式流处理平台&#xff0c;具有高吞吐量、低延迟和可扩展性等特性。它被广泛应用于实时数据处理和流式数据传输的场景。然而&#xff0c;为了将云消息队列 Kafka 版与其他数…

西门子消防主机控制面板显示盘维修B3Q565

作为图形监控主机&#xff0c;负责接收并储存各消防设备主要运行状态&#xff0c;接收火灾报警并显示报警部位&#xff0c;包括火灾报警、状态监视、设备故障报警、网络故障报警﹐指挥抢险救援的活动,进行火灾信息的处理与传送&#xff0c;同时具备提示操作人员的功能&#xff…

Time-series forecasting with deep learning: a survey

人们开发了许多深度学习架构来适应不同领域的时间序列数据集的多样性。在本文中&#xff0c;我们调查了一步前进和多水平时间序列预测中使用的常见编码器和解码器设计&#xff0c;描述了如何将时间信息纳入每个模型的预测中。接下来&#xff0c;我们重点介绍混合深度学习模型的…

信息系统项目管理师好考吗?知识点分析与讲解,码住!

科目一&#xff1a;综合知识考试 科目一考试是由选择题组成的&#xff0c;共有75道题目。考试时间为早上9点到11点半&#xff0c;可以提前交卷&#xff0c;通常11点左右就能离开考场。对于会做的题目&#xff0c;要及时解答&#xff0c;对于不会做的题目&#xff0c;花费过多时…

【EI会议征稿通知】第三届智能电网与绿色能源国际学术会议(ICSGGE 2024)

第三届智能电网与绿色能源国际学术会议&#xff08;ICSGGE 2024&#xff09; 2024 3rd International Conference on Smart Grid and Green Energy 2024年第三届智能电网与绿色能源国际学术会议&#xff08;ICSGGE 2024&#xff09;将于2024年4月19-21日在中国成都举行。会议…