![]() |
Chilkat HOME Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi DLL Go Java JavaScript Node.js Objective-C PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(SQL Server) Implementing DPoP with OAuth2 Client CredentialsSee more AI ExamplesDemonstrating Proof-of-Possession (DPoP) is an OAuth 2.0 extension (RFC 9449) that secures access tokens by binding them to a specific client’s private key, preventing stolen token misuse. It requires the client to sign a JWT (DPoP Proof) with every request, proving they hold the private key.This example shows how to use Chilkat v11.4.0 or later to automatically add the following headers to HTTP requests: Authorization: DPoP <access_token> DPoP: <new JWT signed with same key> Note: This example requires Chilkat v11.4.0 or greater.
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls. -- CREATE PROCEDURE ChilkatSample AS BEGIN DECLARE @hr int DECLARE @iTmp0 int -- Important: Do not use nvarchar(max). See the warning about using nvarchar(max). DECLARE @sTmp0 nvarchar(4000) DECLARE @success int SELECT @success = 0 DECLARE @privKey int EXEC @hr = sp_OACreate 'Chilkat.PrivateKey', @privKey OUT IF @hr <> 0 BEGIN PRINT 'Failed to create ActiveX component' RETURN END -- Load your ECDSA private key. (Keys uses with DPoP must always be ECDSA keys. Not RSA.) EXEC sp_OAMethod @privKey, 'LoadAnyFormatFile', @success OUT, 'qa_data/pem/ecc_privKey.pem', '' IF @success = 0 BEGIN EXEC sp_OAGetProperty @privKey, 'LastErrorText', @sTmp0 OUT PRINT @sTmp0 EXEC @hr = sp_OADestroy @privKey RETURN END DECLARE @tokenEndpoint nvarchar(4000) SELECT @tokenEndpoint = 'https://demo.duendesoftware.com/connect/token' DECLARE @apiEndpoint nvarchar(4000) SELECT @apiEndpoint = 'https://demo.duendesoftware.com/api/dpop/test' -- Provide the details needed for Chilkat to automatically fetch the access token -- using the client_credentials OAuth2 flow. DECLARE @json int EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @json OUT EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'client_secret', 'secret' EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'client_id', 'm2m.dpop' EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'token_endpoint', @tokenEndpoint EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'scope', 'api' DECLARE @http int EXEC @hr = sp_OACreate 'Chilkat.Http', @http OUT EXEC sp_OASetProperty @http, 'SessionLogFilename', 'c:/aaworkarea/sessionLog.txt' -- Provide private key to be used with DPoP EXEC sp_OAMethod @http, 'SetDPoPKey', @success OUT, @privKey IF @success = 0 BEGIN EXEC sp_OAGetProperty @http, 'LastErrorText', @sTmp0 OUT PRINT @sTmp0 EXEC @hr = sp_OADestroy @privKey EXEC @hr = sp_OADestroy @json EXEC @hr = sp_OADestroy @http RETURN END EXEC sp_OAMethod @json, 'Emit', @sTmp0 OUT EXEC sp_OASetProperty @http, 'AuthToken', @sTmp0 -- When we make the first request to an API endpoint, we don't yet have -- an OAuth2 access token. Chilkat (internally) will use the token endpoint -- to automatically get an access token. -- Chilkat will then add the following headers to the request sent to the API endpoint: -- Authorization: DPoP <access_token> -- DPoP: <new JWT signed with same key> -- For subsequent requests using the same Chilkat HTTP object instance, -- the same access token will be used with a newly generated DPoP header for each request. -- When the access_token is expired or about to expire, Chilkat will automatically (internally) -- refresh the access token. Your application does not need to be concerned with the -- complexities of fetching the access token or managing the refresh, or generating -- the DPoP header for each request. DECLARE @resp nvarchar(4000) EXEC sp_OAMethod @http, 'QuickGetStr', @resp OUT, @apiEndpoint EXEC sp_OAGetProperty @http, 'LastMethodSuccess', @iTmp0 OUT IF @iTmp0 = 0 BEGIN EXEC sp_OAGetProperty @http, 'LastErrorText', @sTmp0 OUT PRINT @sTmp0 EXEC @hr = sp_OADestroy @privKey EXEC @hr = sp_OADestroy @json EXEC @hr = sp_OADestroy @http RETURN END DECLARE @statusCode int EXEC sp_OAGetProperty @http, 'LastStatus', @statusCode OUT PRINT 'response status code = ' + @statusCode PRINT @resp -- Here is a Session log showing the raw HTTP request(s) and response(s). -- Notice how Chilkat automatically fetched the access_token and then used it in the API request. -- ---- Sending Mon, 30 Mar 2026 20:09:44 GMT ---- -- POST /connect/token HTTP/1.1 -- Host: demo.duendesoftware.com -- Content-Type: application/x-www-form-urlencoded -- Content-Length: 79 -- DPoP: **** -- -- client_secret=secret&client_id=m2m.dpop&scope=api&grant_type=client_credentials -- ---- Received Mon, 30 Mar 2026 20:09:44 GMT ---- -- HTTP/1.1 200 OK -- Date: Mon, 30 Mar 2026 20:09:43 GMT -- Content-Type: application/json; charset=UTF-8 -- Transfer-Encoding: chunked -- Connection: keep-alive -- Server: Kestrel -- Cache-Control: no-store, no-cache, max-age=0 -- Pragma: no-cache -- X-REVISION: 4f42f7e7 -- -- 374 -- {"access_token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IjE1OEUyRDQ1NzhFNDMyOUJBMzRGNzkxQTQ4Nzk5NzYwIiwieDV0IjoiczkyM2RnYnhWbnhoaTJSZmR1cWZyZXZIYUUwIi -- widHlwIjoiYXQrand0In0.eyJpc3MiOiJodHRwczovL2RlbW8uZHVlbmRlc29mdHdhcmUuY29tIiwibmJmIjoxNzc0OTAxMzgzLCJpYXQiOjE3NzQ5MDEzODMsImV4cCI6MTc3NDkwN -- Dk4MywiYXVkIjoiYXBpIiwiY25mIjp7ImprdCI6IlVMR2J4ZXdNOEZUNDhTd3hKeUY3YnJuMDZWMDdPZ3VpdW41d1ZzSVVENEUifSwic2NvcGUiOlsiYXBpIl0sImNsaWVudF9pZCI6 -- Im0ybS5kcG9wIiwianRpIjoiQ0Q5MjBFQzQyOTRBOTA3QUUyRjMyQjlCREQzQTA3QzMifQ.bbq8tNMVtJp79Wc9xrAsE0h8oOfdxEKtGZ3qHpJX-mvSS4FVXLoO2bfpq1nhFryfbZkk -- ENfoIwSQjb_35aziq2NrnpWwQ4vDF1b9K-b7eJXPmJybm61DAP9HSE3ZI0jMrMTRFLtjwvE4WV6ZXNTwN0Pzn6teog1i09PZQkaGtlJEBjsBaN5N7OsQvtgFLD0sNkjy1JTw5LMNE7u -- 5-W32qv-XDk9KEGfoBkqyt-SR_A2wI7oZvl4OGnYyX8tUOFszlHZKy0_0V3Oc9wkHRM2JZDA_LfTqldJHR5CF5FuNiJ2hp-kioUA-i0gWxhqnVKVspJqQAN3Z95RDl9jSf-pYSg", -- "expires_in":3600,"token_type":"DPoP","scope":"api"} -- 0 -- -- -- ---- Sending Mon, 30 Mar 2026 20:09:44 GMT ---- -- GET /api/dpop/test HTTP/1.1 -- Host: demo.duendesoftware.com -- Accept: */* -- Accept-Encoding: gzip -- Authorization: **** -- DPoP: **** -- -- -- ---- Received Mon, 30 Mar 2026 20:09:44 GMT ---- -- HTTP/1.1 200 OK -- Date: Mon, 30 Mar 2026 20:09:44 GMT -- Content-Type: application/json; charset=utf-8 -- Transfer-Encoding: chunked -- Connection: keep-alive -- Server: Kestrel -- X-REVISION: 4f42f7e7 -- -- 420 -- [{"type":"iss","value":"https://demo.duendesoftware.com"},{"type":"nbf","value":"1774901383"},{"type":"iat","value":"1774901383"}, -- {"type":"exp","value":"1774904983"},{"type":"aud","value":"api"},{"type":"cnf","value":"{\u0022jkt\u0022:\u0022ULGbxewM8FT48SwxJyF7brn06V07Oguiun5wVsIUD4E\u0022}"}, -- {"type":"scope","value":"api"},{"type":"client_id","value":"m2m.dpop"},{"type":"jti","value":"CD920EC4294A907AE2F32B9BDD3A07C3"}, -- {"type":"authorization_scheme","value":"DPoP"},{"type":"proof_token","value":"eyJhbGciOiJFU .... aGrGOgkRXLQ"}] -- 0 -- -- EXEC @hr = sp_OADestroy @privKey EXEC @hr = sp_OADestroy @json EXEC @hr = sp_OADestroy @http END GO |
||||
© 2000-2026 Chilkat Software, Inc. All Rights Reserved.