Skip to content

Instantly share code, notes, and snippets.

@jbyte2009
Created April 22, 2025 18:24
Show Gist options
  • Save jbyte2009/52c04240d25afa0699c14180c29475fb to your computer and use it in GitHub Desktop.
Save jbyte2009/52c04240d25afa0699c14180c29475fb to your computer and use it in GitHub Desktop.
How to use NetSuite REST API with OAuth 2 and C# .NET - New Authorization for April 2025
NetSuite Machine to Machine (M2M) Authentication to authenticate and retrieve an access token.
Visual Studio 2022
Application: Class Library
.NET Core 6 - C#
Package: Portable.BouncyCastle
=========================================
using Microsoft.IdentityModel.Tokens;
using NetSuiteProcessor6.Common.Init;
using NetSuiteProcessor6.Common.Model;
using NetSuiteProcessor6.Model;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System.Collections.Generic;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Security.Cryptography;
using System.Text.Json;
using System.Threading.Tasks;
#nullable disable
namespace NetSuiteProcessor6.Common.OAuth
{
public class NetSuiteApiClient
{
private static string RestApiRoot;
private static string Oauth2ApiRoot;
private static string RecordApiRoot;
private static string TokenEndPointUrl;
private static HttpClient _httpClient;
private static RSACryptoServiceProvider provider;
private static RsaSecurityKey rsaSecurityKey;
private static SigningCredentials signingCreds;
private static PemReader pemRdr;
private static RSAParameters rsaParams;
private static byte[] privateKeyRaw;
private static NsToken response;
private static string responseJson;
private static AuthCred AuthCred;
#region Method | GetAccessToken |
public static async Task<string> GetAccessToken(AuthCred inCred)
{
Init(inCred);
var url = string.Format("{0}/token/", Oauth2ApiRoot);
var clientAssertion = GetJwtToken();
var requestParams = new List<KeyValuePair<string, string>>
{
new("grant_type", "client_credentials"),
new("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"),
new("client_assertion", clientAssertion)
};
var httpRequest = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new FormUrlEncodedContent(requestParams)
};
using (_httpClient = new HttpClient())
{
var httpResponse = await _httpClient.SendAsync(httpRequest);
responseJson = await httpResponse.Content.ReadAsStringAsync();
}
response = JsonSerializer.Deserialize<NsToken>(responseJson);
return response.access_token;
}
#endregion
#region Method | GetJWTToken |
public static string GetJToken(AuthCred inCred)
{
Init(inCred);
var tkn = GetJwtToken();
return tkn;
}
#endregion
#region Method | Init |
private static void Init(AuthCred inCred)
{
AuthCred = inCred;
RestApiRoot = string.Format(sInit.RestApiRoot, inCred.AccountID);
Oauth2ApiRoot = string.Format(sInit.Oauth2ApiRoot, RestApiRoot);
RecordApiRoot = string.Format(sInit.RecordApiRoot, RestApiRoot);
TokenEndPointUrl = string.Format(sInit.TokenEndPointUrl, Oauth2ApiRoot);
}
#endregion
#region Method | GetJwtToken |
private static string GetJwtToken()
{
pemRdr = new PemReader(new StringReader(AuthCred.PrivateKeyPem));
rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)pemRdr.ReadObject());
var provider = RSA.Create(4096);
provider.ImportParameters(rsaParams);
rsaSecurityKey = new RsaSecurityKey(provider);
// Create signature and add to it the certificate ID provided by NetSuite.
signingCreds = new SigningCredentials(rsaSecurityKey, SecurityAlgorithms.RsaSsaPssSha256);
signingCreds.Key.KeyId = AuthCred.ClientCredentialsCertificateId;
// Get issuing timestamp.
var now = DateTime.UtcNow;
// Create token.
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = AuthCred.ApiConsumerKey,
Audience = TokenEndPointUrl,
Expires = now.AddMinutes(5),
IssuedAt = now,
Claims = new Dictionary<string, object> {
{ "scope", new[] { "rest_webservices", "restlets" } }
},
SigningCredentials = signingCreds
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenText = tokenHandler.WriteToken(token);
return tokenText;
}
#endregion
}
}
@jbyte2009
Copy link
Author

Some variables that I store in a Resource file:

RestApiRoot = https://[account id].suitetalk.api.netsuite.com/services/rest

Oauth2ApiRoot = https://[account id].suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1

TokenEndPointUrl = https://[account id].suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment