DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
JWTToken.cpp
Go to the documentation of this file.
1#include "pch.h"
4#include "System/Convert.h"
7#include <cstring>
8#include <string>
9
10namespace DotNetDupe {
11 namespace System {
12 namespace IdentityModel {
13 namespace Tokens {
14 namespace Jwt {
15
16 static String Base64ToBase64Url(const String& base64) {
18 std::string s = base64.GetRawString();
19 for (char& c : s) {
20 if (c == '+') c = '-';
21 else if (c == '/') c = '_';
22 }
23 while (!s.empty() && s.back() == '=') {
24 s.pop_back();
25 }
26 return String(s.c_str());
27 }
28
29 static String Base64UrlToBase64(const String& base64Url) {
31 std::string s = base64Url.GetRawString();
32 for (char& c : s) {
33 if (c == '-') c = '+';
34 else if (c == '_') c = '/';
35 }
36 while (s.length() % 4 != 0) {
37 s += '=';
38 }
39 return String(s.c_str());
40 }
41
44 m_header.Add("alg", "HS256");
45 m_header.Add("typ", "JWT");
46 }
47
52
57
62
67
70 return m_signature;
71 }
72
80
81 static String ComputeJwtSignature(const String& rawToken, const String& secretKey) {
83 Array<char> tokenBytes(rawToken.GetLength());
84 std::memcpy(tokenBytes.GetData(), rawToken.GetRawString(), rawToken.GetLength());
85 Array<char> keyBytes(secretKey.GetLength());
86 std::memcpy(keyBytes.GetData(), secretKey.GetRawString(), secretKey.GetLength());
89 }
90
93 String headerB64Url = EncodeDictToBase64Url(m_header);
94 String payloadB64Url = EncodeDictToBase64Url(m_payload);
95 m_rawTokenWithoutSignature = headerB64Url + "." + payloadB64Url;
96 m_signature = ComputeJwtSignature(m_rawTokenWithoutSignature, secretKey);
97 return m_rawTokenWithoutSignature + "." + m_signature;
98 }
99
107
110 Array<String> parts = tokenStr.Split('.');
111 if (parts.GetLength() != 3) throw ArgumentException("Invalid JWT token format.");
112
114 auto pToken = SmartPointer<JWTToken>::NewShared();
115 pToken->m_header = DecodeBase64UrlToDict(parts[0]);
116 pToken->m_payload = DecodeBase64UrlToDict(parts[1]);
117 pToken->m_rawTokenWithoutSignature = parts[0] + "." + parts[1];
118 pToken->m_signature = parts[2];
119 return pToken;
120 }
121
122 bool JWTToken::Verify(const String& secretKey) const {
124
126 if (m_rawTokenWithoutSignature.IsEmpty() || m_signature.IsEmpty()) {
127 return false;
128 }
129
131 Array<char> tokenBytes(m_rawTokenWithoutSignature.GetLength());
132 std::memcpy(tokenBytes.GetData(), m_rawTokenWithoutSignature.GetRawString(), m_rawTokenWithoutSignature.GetLength());
133
134 Array<char> keyBytes(secretKey.GetLength());
135 std::memcpy(keyBytes.GetData(), secretKey.GetRawString(), secretKey.GetLength());
136
137 Array<char> signatureHash = HMACSHA256::ComputeHash(tokenBytes, keyBytes);
138 String signatureB64 = Convert::ToBase64String(signatureHash);
139 String expectedSignature = Base64ToBase64Url(signatureB64);
140
142 return m_signature == expectedSignature;
143 }
144
145 }
146 }
147 }
148 }
149}
Defines the exception thrown when an invalid argument is provided to a method.
Converts a base data type to another base data type, and encodes/decodes Base64 data.
Hash-based Message Authentication Code using SHA-256 per RFC 2104.
JSON Web Token (JWT) representation and cryptographic operations per RFC 7519.
Provides functionality to serialize objects to JSON strings and deserialize JSON strings into objects...
ArgumentException(const String &sMessage)
Initializes a new instance of the ArgumentException class with a specified error message.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition Array.h:29
int GetLength() const
Gets the total number of elements in all dimensions of the Array.
Definition Array.h:142
T * GetData()
Gets a pointer to the contiguous internal element buffer.
Definition Array.h:146
Represents a collection of keys and values.
Definition Dictionary.h:66
static Array< char > FromBase64String(const String &s)
Definition Convert.cpp:392
static String ToBase64String(const Array< char > &inArray)
Definition Convert.cpp:325
String GetSignature() const
Gets the cryptographic signature string component of the token.
Definition JWTToken.cpp:68
Collections::Generic::Dictionary< String, String > & GetPayload()
Gets a mutable reference to the payload claims dictionary.
Definition JWTToken.cpp:58
String CreateToken(const String &secretKey)
Encodes and cryptographically signs the token using HMAC-SHA256.
Definition JWTToken.cpp:91
static SmartPointer< JWTToken > Parse(const String &tokenStr)
Parses a serialized compact JWT string into a JWTToken instance.
Definition JWTToken.cpp:108
JWTToken()
Initializes a new instance of the JWTToken class with default header values.
Definition JWTToken.cpp:42
Collections::Generic::Dictionary< String, String > & GetHeader()
Gets a mutable reference to the JOSE header dictionary.
Definition JWTToken.cpp:48
bool Verify(const String &secretKey) const
Verifies the token signature against a specified secret key.
Definition JWTToken.cpp:122
Array< char > ComputeHash(const Array< char > &buffer)
Computes the HMAC hash value for the specified byte array.
A unified smart pointer that supports both unique and shared ownership semantics.
static SmartPointer< T > NewShared()
Creates a Shared SmartPointer, default constructing T.
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
Definition String.h:74
String()
Initializes a new instance of the String class to an empty string.
Definition String.cpp:64
const char * GetRawString() const
Definition String.cpp:230
Array< String > Split(char chSeparator) const
Definition String.cpp:552
static T Deserialize(const String &sJson)
Parses the text representing a single JSON value into an instance of the type specified by a generic ...
static String Serialize(const T &value)
Converts the value of a type specified by a generic type parameter into a JSON string.
static String EncodeDictToBase64Url(const Collections::Generic::Dictionary< String, String > &dict)
Definition JWTToken.cpp:73
static Collections::Generic::Dictionary< String, String > DecodeBase64UrlToDict(const String &b64url)
Definition JWTToken.cpp:100
static String Base64ToBase64Url(const String &base64)
Definition JWTToken.cpp:16
static String ComputeJwtSignature(const String &rawToken, const String &secretKey)
Definition JWTToken.cpp:81
static String Base64UrlToBase64(const String &base64Url)
Definition JWTToken.cpp:29