Skip to content
This repository was archived by the owner on Nov 23, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
https://github.com/zendesk/classic_asp_jwt.git

## Classic ASP JWT

A JWT implementation in Classic ASP, currently only supports `JWTEncode(dictionary, secret)`.
Expand All @@ -7,7 +9,7 @@ A JWT implementation in Classic ASP, currently only supports `JWTEncode(dictiona
```asp
<!--#include file="jwt.asp" -->
<%
Dim sKey, dAttributes, sToken
Dim sKey, dAttributes, sToken, decodedPayload, isValidJWT

sKey = "Shared Secret"
Set dAttributes=Server.CreateObject("Scripting.Dictionary")
Expand All @@ -19,6 +21,12 @@ dAttributes.Add "name", "Roger"
dAttributes.Add "email", "[email protected]"

sToken = JWTEncode(dAttributes, sKey)

' Decode JWT token string and get payload. (WARNING : Not verify)
decodedPayload = JWTDecode(sToken)

' Verify JWT String. (Returns Boolean)
isValidJWT = JWTVerify(sToken, sKey)
%>
```

Expand Down
249 changes: 149 additions & 100 deletions external/aspJSON.asp
Original file line number Diff line number Diff line change
@@ -1,113 +1,135 @@
<%
'July 2012 - Version 1.0 by Gerrit van Kuipers - http://www.aspjson.com/
'January 2021 - Version 1.1 by Gerrit van Kuipers
Class aspJSON
Public data
Private p_JSONstring
Private p_datatype
Private aj_in_string, aj_in_escape, aj_i_tmp, aj_char_tmp, aj_s_tmp, aj_line_tmp, aj_line, aj_lines, aj_currentlevel, aj_currentkey, aj_currentvalue, aj_newlabel, aj_XmlHttp, aj_RegExp, aj_colonfound

Private Sub Class_Initialize()
Set data = Collection()
p_datatype = "{}"

Set aj_RegExp = New regexp
aj_RegExp.Pattern = "\s{0,}(\S{1}[\s,\S]*\S{1})\s{0,}"
aj_RegExp.Global = False
aj_RegExp.IgnoreCase = True
aj_RegExp.Multiline = True
End Sub

Private Sub Class_Terminate()
Set data = Nothing
Set aj_RegExp = Nothing
End Sub

Public Function loadJSON(strInput)
p_JSONstring = CleanUpJSONstring(Trim(strInput))
lines = Split(p_JSONstring, vbCrLf)
Public Sub loadJSON(inputsource)
inputsource = aj_MultilineTrim(inputsource)
If Len(inputsource) = 0 Then Err.Raise 1, "loadJSON Error", "No data to load."

Select Case Left(inputsource, 1)
Case "{", "["
Case Else
Set aj_XmlHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")
aj_XmlHttp.open "POST", inputsource, False
aj_XmlHttp.setRequestHeader "Content-Type", "text/json"
aj_XmlHttp.setRequestHeader "CharSet", "UTF-8"
aj_XmlHttp.Send
inputsource = aj_XmlHttp.responseText
Set aj_XmlHttp = Nothing
End Select

p_JSONstring = CleanUpJSONstring(inputsource)
aj_lines = Split(p_JSONstring, Chr(13) & Chr(10))

Dim level(99)
currentlevel = 1
Set level(currentlevel) = data
For Each line In lines
currentkey = ""
currentvalue = ""
If Instr(line, ":") > 0 Then
'"created":"2010-04-30 09:20:09"

in_string = False
in_escape = False
For i_tmp = 1 To Len(line)
If in_escape Then
in_escape = False
aj_currentlevel = 1
Set level(aj_currentlevel) = data
For Each aj_line In aj_lines
aj_currentkey = ""
aj_currentvalue = ""
If Instr(aj_line, ":") > 0 Then
aj_in_string = False
aj_in_escape = False
aj_colonfound = False
For aj_i_tmp = 1 To Len(aj_line)
If aj_in_escape Then
aj_in_escape = False
Else
char = Mid(line, i_tmp, 1)
Select Case char
Select Case Mid(aj_line, aj_i_tmp, 1)
Case """"
in_string = Not in_string
aj_in_string = Not aj_in_string
Case ":"
If Not in_escape Then
currentkey = Left(line, i_tmp - 1)
currentvalue = Mid(line, i_tmp + 1)
If Not aj_in_escape And Not aj_in_string Then
aj_currentkey = Left(aj_line, aj_i_tmp - 1)
aj_currentvalue = Mid(aj_line, aj_i_tmp + 1)
aj_colonfound = True
Exit For
End If
Case "\"
in_escape = True
aj_in_escape = True
End Select
End If
Next
currentkey = Strip(JSONDecode(currentkey), """")
If Not level(currentlevel).exists(currentkey) Then level(currentlevel).Add currentkey, ""
if aj_colonfound then
aj_currentkey = aj_Strip(aj_JSONDecode(aj_currentkey), """")
If Not level(aj_currentlevel).exists(aj_currentkey) Then level(aj_currentlevel).Add aj_currentkey, ""
end if
End If
If Instr(line,"{") > 0 Or Instr(line,"[") > 0 Then
If Len(currentkey) = 0 Then currentkey = level(currentlevel).Count
Set level(currentlevel).Item(currentkey) = Collection()
Set level(currentlevel + 1) = level(currentlevel).Item(currentkey)
currentlevel = currentlevel + 1
currentkey = ""
ElseIf Instr(line,"}") > 0 Or Instr(line,"]") > 0 Then
currentlevel = currentlevel - 1
ElseIf Len(Trim(line)) > 0 Then
if Len(currentvalue) = 0 Then currentvalue = getJSONValue(line)
currentvalue = getJSONValue(currentvalue)

If Len(currentkey) = 0 Then currentkey = level(currentlevel).Count
level(currentlevel).Item(currentkey) = currentvalue
If right(aj_line,1) = "{" Or right(aj_line,1) = "[" Then
If Len(aj_currentkey) = 0 Then aj_currentkey = level(aj_currentlevel).Count
Set level(aj_currentlevel).Item(aj_currentkey) = Collection()
Set level(aj_currentlevel + 1) = level(aj_currentlevel).Item(aj_currentkey)
aj_currentlevel = aj_currentlevel + 1
aj_currentkey = ""
ElseIf right(aj_line,1) = "}" Or right(aj_line,1) = "]" or right(aj_line,2) = "}," Or right(aj_line,2) = "]," Then
aj_currentlevel = aj_currentlevel - 1
ElseIf Len(Trim(aj_line)) > 0 Then
If Len(aj_currentvalue) = 0 Then aj_currentvalue = aj_line
aj_currentvalue = getJSONValue(aj_currentvalue)

If Len(aj_currentkey) = 0 Then aj_currentkey = level(aj_currentlevel).Count
level(aj_currentlevel).Item(aj_currentkey) = aj_currentvalue
End If
Next
End Function
End Sub

Public Function Collection()
set Collection = Server.CreateObject("Scripting.Dictionary")
Set Collection = Server.CreateObject("Scripting.Dictionary")
End Function

Public Function AddToCollection(dictobj)
if TypeName(dictobj) <> "Dictionary" then Err.Raise 1, "AddToCollection Error", "Not a collection."
newlabel = dictobj.Count
dictobj.Add newlabel, Collection()
set AddToCollection = dictobj.item(newlabel)
If TypeName(dictobj) <> "Dictionary" Then Err.Raise 1, "AddToCollection Error", "Not a collection."
aj_newlabel = dictobj.Count
dictobj.Add aj_newlabel, Collection()
Set AddToCollection = dictobj.item(aj_newlabel)
end function

Private Function CleanUpJSONstring(originalstring)
originalstring = Replace(originalstring,vbCrLf, "")

p_datatype = Left(originalstring, 1) & Right(originalstring, 1)
originalstring = Mid(originalstring, 2, Len(originalstring) - 2)
in_string = False : in_escape = False
For i_tmp = 1 To Len(originalstring)
If in_escape Then
in_escape = False
Private Function CleanUpJSONstring(aj_originalstring)
aj_originalstring = Replace(aj_originalstring, Chr(13) & Chr(10), "")
aj_originalstring = Mid(aj_originalstring, 2, Len(aj_originalstring) - 2)
aj_in_string = False : aj_in_escape = False : aj_s_tmp = ""
For aj_i_tmp = 1 To Len(aj_originalstring)
aj_char_tmp = Mid(aj_originalstring, aj_i_tmp, 1)
If aj_in_escape Then
aj_in_escape = False
aj_s_tmp = aj_s_tmp & aj_char_tmp
Else
char_tmp = Mid(originalstring, i_tmp, 1)
Select Case char_tmp
Case "\" : in_escape = True
Case """" : s_tmp = s_tmp & char_tmp : in_string = Not in_string
Select Case aj_char_tmp
Case "\" : aj_s_tmp = aj_s_tmp & aj_char_tmp : aj_in_escape = True
Case """" : aj_s_tmp = aj_s_tmp & aj_char_tmp : aj_in_string = Not aj_in_string
Case "{", "["
s_tmp = s_tmp & char_tmp & InlineIf(in_string, "", vbCrLf)
aj_s_tmp = aj_s_tmp & aj_char_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10))
Case "}", "]"
s_tmp = s_tmp & InlineIf(in_string, "", vbCrLf) & char_tmp
Case "," : s_tmp = s_tmp & char_tmp & InlineIf(in_string, "", vbCrLf)
Case Else : s_tmp = s_tmp & char_tmp
aj_s_tmp = aj_s_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10)) & aj_char_tmp
Case "," : aj_s_tmp = aj_s_tmp & aj_char_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10))
Case Else : aj_s_tmp = aj_s_tmp & aj_char_tmp
End Select
End If
Next

CleanUpJSONstring = ""
s_tmp = split(s_tmp, vbCrLf)
For Each line_tmp In s_tmp
CleanUpJSONstring = CleanUpJSONstring & Trim(line_tmp) & vbCrLf
aj_s_tmp = Split(aj_s_tmp, Chr(13) & Chr(10))
For Each aj_line_tmp In aj_s_tmp
aj_line_tmp = Replace(Replace(aj_line_tmp, Chr(10), ""), Chr(13), "")
CleanUpJSONstring = CleanUpJSONstring & aj_Trim(aj_line_tmp) & Chr(13) & Chr(10)
Next
End Function

Expand All @@ -124,53 +146,58 @@ Class aspJSON
Case Else
If (Instr(val, """") = 0) Then
If IsNumeric(val) Then
getJSONValue = CDbl(val)
getJSONValue = aj_ReadNumericValue(val)
Else
getJSONValue = val
End If
Else
If Left(val,1) = """" Then val = Mid(val, 2)
If Right(val,1) = """" Then val = Left(val, Len(val) - 1)
getJSONValue = JSONDecode(Trim(val))
getJSONValue = aj_JSONDecode(Trim(val))
End If
End Select
End Function

Private JSONoutput_level
Public Function JSONoutput()
Dim wrap_dicttype, aj_label
JSONoutput_level = 1
JSONoutput = Left(p_datatype, 1) & vbCrLf & GetDict(data) & Right(p_datatype, 1)
wrap_dicttype = "[]"
For Each aj_label In data
If Not aj_IsInt(aj_label) Then wrap_dicttype = "{}"
Next
JSONoutput = Left(wrap_dicttype, 1) & Chr(13) & Chr(10) & GetDict(data) & Right(wrap_dicttype, 1)
End Function

Private Function GetDict(objDict)
For Each item In objDict
Select Case TypeName(objDict.Item(item))
Dim aj_item, aj_keyvals, aj_label, aj_dicttype
For Each aj_item In objDict
Select Case TypeName(objDict.Item(aj_item))
Case "Dictionary"
GetDict = GetDict & Space(JSONoutput_level * 4)

dicttype = "[]"
For Each label In objDict.Item(item).Keys
If Not IsInt(label) Then dicttype = "{}"
aj_dicttype = "[]"
For Each aj_label In objDict.Item(aj_item).Keys
If Not aj_IsInt(aj_label) Then aj_dicttype = "{}"
Next

If IsInt(item) Then
GetDict = GetDict & Left(dicttype,1) & vbCrLf
If aj_IsInt(aj_item) Then
GetDict = GetDict & (Left(aj_dicttype,1) & Chr(13) & Chr(10))
Else
GetDict = GetDict & """" & JSONEncode(item) & """" & ": " & Left(dicttype,1) & vbCrLf
GetDict = GetDict & ("""" & aj_JSONEncode(aj_item) & """" & ": " & Left(aj_dicttype,1) & Chr(13) & Chr(10))
End If
JSONoutput_level = JSONoutput_level + 1

keyvals = objDict.Keys
GetDict = GetDict & GetSubDict(objDict.Item(item)) & Space(JSONoutput_level * 4) & Right(dicttype,1) & InlineIf(item = keyvals(objDict.Count - 1),"" , ",") & vbCrLf
aj_keyvals = objDict.Keys
GetDict = GetDict & (GetSubDict(objDict.Item(aj_item)) & Space(JSONoutput_level * 4) & Right(aj_dicttype,1) & aj_InlineIf(aj_item = aj_keyvals(objDict.Count - 1),"" , ",") & Chr(13) & Chr(10))
Case Else
keyvals = objDict.Keys
GetDict = GetDict & Space(JSONoutput_level * 4) & InlineIf(IsInt(item), "", """" & JSONEncode(item) & """: ") & WriteValue(objDict.Item(item)) & InlineIf(item = keyvals(objDict.Count - 1),"" , ",") & vbCrLf
aj_keyvals = objDict.Keys
GetDict = GetDict & (Space(JSONoutput_level * 4) & aj_InlineIf(aj_IsInt(aj_item), "", """" & aj_JSONEncode(aj_item) & """: ") & WriteValue(objDict.Item(aj_item)) & aj_InlineIf(aj_item = aj_keyvals(objDict.Count - 1),"" , ",") & Chr(13) & Chr(10))
End Select
Next
End Function

Private Function IsInt(val)
IsInt = (TypeName(val) = "Integer" Or TypeName(val) = "Long")
Private Function aj_IsInt(val)
aj_IsInt = (TypeName(val) = "Integer" Or TypeName(val) = "Long")
End Function

Private Function GetSubDict(objSubDict)
Expand All @@ -180,14 +207,14 @@ Class aspJSON

Private Function WriteValue(ByVal val)
Select Case TypeName(val)
Case "Double", "Integer", "Long": WriteValue = val
Case "Double", "Integer", "Long": WriteValue = replace(val, ",", ".")
Case "Null" : WriteValue = "null"
Case "Boolean" : WriteValue = InlineIf(val, "true", "false")
Case Else : WriteValue = """" & JSONEncode(val) & """"
Case "Boolean" : WriteValue = aj_InlineIf(val, "true", "false")
Case Else : WriteValue = """" & aj_JSONEncode(val) & """"
End Select
End Function

Private Function JSONEncode(ByVal val)
Private Function aj_JSONEncode(ByVal val)
val = Replace(val, "\", "\\")
val = Replace(val, """", "\""")
'val = Replace(val, "/", "\/")
Expand All @@ -196,10 +223,10 @@ Class aspJSON
val = Replace(val, Chr(10), "\n")
val = Replace(val, Chr(13), "\r")
val = Replace(val, Chr(9), "\t")
JSONEncode = Trim(val)
aj_JSONEncode = Trim(val)
End Function

Private Function JSONDecode(ByVal val)
Private Function aj_JSONDecode(ByVal val)
val = Replace(val, "\""", """")
val = Replace(val, "\\", "\")
val = Replace(val, "\/", "/")
Expand All @@ -208,17 +235,39 @@ Class aspJSON
val = Replace(val, "\n", Chr(10))
val = Replace(val, "\r", Chr(13))
val = Replace(val, "\t", Chr(9))
JSONDecode = Trim(val)
aj_JSONDecode = Trim(val)
End Function

Private Function InlineIf(condition, returntrue, returnfalse)
If condition Then InlineIf = returntrue Else InlineIf = returnfalse
Private Function aj_InlineIf(condition, returntrue, returnfalse)
If condition Then aj_InlineIf = returntrue Else aj_InlineIf = returnfalse
End Function

Private Function Strip(ByVal val, stripper)
Private Function aj_Strip(ByVal val, stripper)
If Left(val, 1) = stripper Then val = Mid(val, 2)
If Right(val, 1) = stripper Then val = Left(val, Len(val) - 1)
Strip = val
aj_Strip = val
End Function

Private Function aj_MultilineTrim(TextData)
aj_MultilineTrim = aj_RegExp.Replace(TextData, "$1")
End Function

Private Function aj_Trim(val)
aj_Trim = Trim(val)
Do While Left(aj_Trim, 1) = Chr(9) : aj_Trim = Mid(aj_Trim, 2) : Loop
Do While Right(aj_Trim, 1) = Chr(9) : aj_Trim = Left(aj_Trim, Len(aj_Trim) - 1) : Loop
aj_Trim = Trim(aj_Trim)
End Function

Private Function aj_ReadNumericValue(ByVal val)
If Instr(val, ".") > 0 Then
numdecimals = Len(val) - Instr(val, ".")
val = Clng(Replace(val, ".", ""))
val = val / (10 ^ numdecimals)
aj_ReadNumericValue = val
Else
aj_ReadNumericValue = Clng(val)
End If
End Function
End Class
%>
%>
Loading