Skip to content

Instantly share code, notes, and snippets.

@yiskang
Created August 29, 2025 07:12
Show Gist options
  • Select an option

  • Save yiskang/3fd2fdfd753844f8fa12293d67cc5492 to your computer and use it in GitHub Desktop.

Select an option

Save yiskang/3fd2fdfd753844f8fa12293d67cc5492 to your computer and use it in GitHub Desktop.
Demo how to exchange ASP 3LO access token using APS SSA
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>ApsSsaVbConsole</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.14.0" />
</ItemGroup>
</Project>
Imports System
Imports System.Collections.Generic
Imports System.IdentityModel.Tokens.Jwt
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Security.Claims
Imports System.Security.Cryptography
Imports System.Text
Imports System.Threading.Tasks
Imports Microsoft.IdentityModel.Tokens
Imports System.Net.Http.Json
Imports Newtonsoft.Json.Linq
Module Program
Sub Main(args As String())
Dim APS_CLIENT_ID As String = "YOUR_CLIENT_ID"
Dim APS_CLIENT_SECRET As String = "YOUR_CLIENT_SECRET"
Dim SERVICE_ACCOUNT_ID As String = "YOUR_SSA_ACOUNT_ID"
Dim KEY_ID As String = "YOUR_SSA_KEY_ID"
Dim PRIVATE_KEY As String = "-----BEGIN RSA PRIVATE KEY-----
YOUR_PRIVATE_KEY
-----END RSA PRIVATE KEY-----"
Dim SCOPE As String() = {"data:read", "data:write"}
Dim jwtAssertion As String = GenerateJwtAssertion(KEY_ID, PRIVATE_KEY, APS_CLIENT_ID, SERVICE_ACCOUNT_ID, SCOPE)
Dim tokenResponse As String = GetAccessToken(jwtAssertion, APS_CLIENT_ID, APS_CLIENT_SECRET, SCOPE).Result
Console.WriteLine("Access Token Response:")
Console.WriteLine(tokenResponse)
End Sub
Function GenerateJwtAssertion(keyId As String, privateKeyPem As String, clientId As String, ssa_id As String, scope As String()) As String
' Create RSA from the PEM-formatted private key
Using rsa As RSA = RSA.Create()
privateKeyPem = privateKeyPem.Replace(vbCrLf, vbLf)
rsa.ImportFromPem(privateKeyPem.ToCharArray())
Dim securityKey As New RsaSecurityKey(rsa) With {
.keyId = keyId
}
Dim signingCredentials As New SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256)
' Build JWT claims
Dim claims As New List(Of Claim) From {
New Claim("iss", clientId),
New Claim("sub", ssa_id),
New Claim("aud", "https://developer.api.autodesk.com/authentication/v2/token")
}
For Each scopeStr As String In scope
claims.Add(New Claim("scope", scopeStr))
Next
' Create the token with a 5-minute expiration
Dim jwtToken As New JwtSecurityToken(
claims:=claims,
expires:=DateTime.UtcNow.AddSeconds(300),
signingCredentials:=signingCredentials
)
Dim tokenHandler As New JwtSecurityTokenHandler()
Return tokenHandler.WriteToken(jwtToken)
End Using
End Function
Async Function GetAccessToken(jwtAssertion As String, clientId As String, clientSecret As String, scope As String()) As Task(Of String)
Using client As New HttpClient()
Dim request As New HttpRequestMessage(HttpMethod.Post, "https://developer.api.autodesk.com/authentication/v2/token")
request.Headers.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
request.Content = New FormUrlEncodedContent(New Dictionary(Of String, String) From {
{"grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"},
{"assertion", jwtAssertion},
{"scope", String.Join(" ", scope)}
})
' Encode client ID and secret for basic auth
Dim authenticationString As String = $"{clientId}:{clientSecret}"
Dim base64EncodedAuthenticationString As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(authenticationString))
request.Headers.Authorization = New AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString)
Try
Dim response = Await client.SendAsync(request)
Dim msg As String = Await response.Content.ReadAsStringAsync()
Console.WriteLine(msg)
response.EnsureSuccessStatusCode()
Return msg
Catch ex As Exception
Throw New InvalidOperationException()
End Try
End Using
End Function
End Module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment