You are not logged in.
Pages: 1
Btw Daniel, verifying JWT in mORMot2 is a rather easy process (once you have a public key):
function VerifyToken(const APublicKey: RawByteString; const AToken: RawUTF8): boolean;
var
FToken: TJWTAbstract;
jwt: TJWTContent;
begin
FToken := TJwtCrypt.Create(caaRS256, APublicKey, [jrcIssuer], []);
FToken.Options := [joHeaderParse, joAllowUnexpectedClaims];
FToken.Verify(access_token, jwt);
Result := jwt.result = jwtValid;
end;
Thanks a lot Arnaud and Daniel for helping out. I have created a gist to explain a bit better with examples on what I want to achieve:
https://gist.github.com/cadnan/532751ef … 7543a2947c
We are at the moment using Keycloak as an OpenID Connect identity provider. Keycloak has a unique feature where you can access its public key in an easy json response from a specific url of your realm. However, this is not a standardized way.. I am scared to see that Microsoft has it's own way of doing it. AFAIK, if you have a .wellknown URL for your identity provider you should have a jwks_uri property which should give you a list of certificates with the famous x5c field.
In my gist I have explained how I extracted public key from x5c but using command line tools (certutil and openssl). It would be great if such could be achieved by mORMot2 and I have a feeling we have everything in place for that.
The task is rather simple, but somehow I cannot make it happen.
I would like to validate a JWT that is received when performing OAuth2 authentication. In order to obtain public key of the server I need to get JWKS from its URL. JWKS provides values like: "kid", "kty", "alg", "use", "n", "e", "x5c", "x5t", "x5t#S256". "x5c" is of interest here as it is a base64 encoded certificate chain containing public key. And here comes my problem. The following (minimal) code is not working for me:
procedure ChainInfo;
var
cert_chain: TX509;
cert_rawbytes: rawbytestring;
begin
cert_chain := TX509.Create;
try
cert_rawbytes := Base64ToBin('MIICo......'); // value from "x5c" field
if cert_chain.LoadFromDer(cert_rawbytes) then
ShowMessage(cert_chain.PeerInfo);
finally
cert_chain.Free;
end;
end;
By not working I mean I always get false result from LoadFromDer function.
I tried saving to a file (cert.crt) the cert_rawbytes content and viewing it with openssl which reported a lot of problems with the file.
Interestingly, if I decode x5c field using TNetEncoding.Base64.DecodeStringToBytes('MIICo...') and save the resulting TBytes to a file, I can view the content of the file with openssl. But the moment I convert those same TBytes to RawByteString I am again failing to view the content of the file.
So, something rather obvious I am missing but just cannot figure it out..
Request for inclusion submitted!
At the end description I used was: "An Open Source high-performance framework for modern Object Pascal that enables ORM, SOA, MVC, RESTful APIs, and client-server applications development."
And tags that I used are: "ORM, SOA, MVC, REST, API, JSON, JWT, Cryptography, OpenSSL, X.509, LDAP, Database, SQLite, MongoDB, HTTP, HTTPS, TLS, WebSocket, Server, Client, Framework, Open Source, High Performance, Asynchronous, Web Services, RPC, NoSQL, SQL"
I've deliberately avoided cross-platform here as the cross-platform feature is not possible in Delphi itself but rather in FPC. I just wanted to minimize the potential discussion points with Embarcadero regarding inclusion of mORMot2 in GetIt.
Fingers crossed!
Arnaud, have a nice time in Denmark and Germany. Please share the slides once the events are finished (as you usually do).
Thanks @flydev for having a look at this! Great comments.
I am personally not a fan of LLMs but I agree that they can provide a rather professional summary of mORMot2 framework!
I have started filling in the form for GetIt inclusion of mORMo2. It would be good if primarily Arnaud, but also other members of this community could give me some comments on the following:
1. We need to provide a "short" description of the product (yea, good luck with that with mORMot). Currently I just copy pasted the following: "An Open Source Client-Server ORM/SOA/MVC framework in modern Object Pascal". I personally think that this is not a fair description given that mORMot can do so much more, but it is a start.
2. We need to provide a link to the image to be used for the project, preferably in the size 154x154. My candidate: https://blog.synopse.info/public/blog/mORMot2-small.png
3. Project homepage: https://github.com/synopse/mormot2
4. Vendor name is Synopse. Vendor url is: https://synopse.info and vendor contact is email starting as webcontact01
5. Supported products: Delphi (I guess we do not support C++ Builder, right? I personally never tried such a combo)
6. Tags (search keywords): ORM, SOA, MVC, Web, REST, API, JSON, JWT, Crypt, OpenSSL, x509, LDAP, DB, SQLite, MongoDB, HTTP, WebSocket, Server, Client (please comment on these)
Given that the company I work for has an Enterprise Delphi licenses for many years for a team of 10+ people and we do use mORMot, I could give it a try and take on this process.
Although we do have challenges with GetIt (like we cannot specify an exact version that we would like to download) I can still motivate that our company "really needs mORMot2 in GetIt"..
Another idea is to push mormot into https://delphi.dev/. Now this idea I like very much but it will take some time to have its momentum.
I cannot even try to explain the pain we (as a team) are having with Delphi and components. We are actively using Delphi 2007, Delphi 11 and Delphi 12 on the same machine with 15+ open source and commercial components installed. If all components would be like mormot (unpack and set path) what a joy life would be.
What? We don't have audio processing in mORMot
@ab, you started this with your 1.0594631 constant...
Thanks Arnaud for your valuable response.
I have tried to implement a package using mormot.core.variants and a VCL application using this package dynamically. Everything works as expected without my changes to the mormot.core.variants. Difficult to blame Delphi RTL for a problem in this case given that we are using a custom/proprietary plugin framework. I simply need to put more effort into debugging if this framework does something out of ordinary.
I am using Delphi 11 and latest mORMot2. When closing an application I have a memory leak pointing to mormot.core.variants. The exception is almost the same as in this topic: Memory leak starting rev. 179, with the exception of TObject.DisposeOf being called last in the call stack.
But, we have a proprietary/custom made plugin framework (host application is loading bpl's at the runtime) and this memory leak is happening only when using this framework inside a bpl loaded by the host and not when using mormot.core.variants directly in the host. Given this situation I did my own analysis and made a fix for which I need your opinion.
Problem seems to be in the SynVariantTypes array and "my fix" was to simply add the DeInitializeUnit at the end of mormot.core.variants:
procedure DeInitializeUnit;
var
i: integer;
begin
SynVariantTypesSafe.Lock;
try
for i := 0 to length(SynVariantTypes) - 1 do
begin
SynVariantTypes[i].Free;
end;
finally
SynVariantTypesSafe.UnLock;
end;
end;
initialization
InitializeUnit;
finalization
DeInitializeUnit;
Is it OK to do it like this? Am I making some huge mistake by doing it like this? Would it harm to have this code in the official release of mORMot2 so I don't have to patch it every time we update the library?
Thanks,
+adnan
Thanks Arnaud!
Indeed, HTTP is a prime example of a custom TCP protocol
I would like to create my own application (instead of the one delivered by a vendor) that communicates with a proprietary system.
They are using a custom/proprietary TCP protocol, but luckily I have a Wireshark dissector for it.
My question is if anyone can give me some hints/tips/starting points in how to achieve this in mORMot2?
My guess is that I will spend a lot of time in mormot.net.sock unit but if someone has a public repo or an example of how one defines custom TCP header, message length bytes etc.. it would be really helpful.
Thanks,
+adnan
I think I found the solution for this.
Once you instantiate a TJwtCrypt class (or similar) you can set Options to [joHeaderParse].
In case I am doing it wrong, please let me know.
Thanks,
+adnan
I am just giving keycloak as an example of a problem.
Keycloak generates a JWT with the following header, for example:
{
"alg": "RS256",
"typ": "JWT",
"kid": "Ov1FFK-avlBR40w6MHNNdCkR5Rl4QcL-STw7h2H11fc"
}
When parsing token this if line is activated in mormot.crypt.jwt, line 1074:
if (toklen <= headerlen) or
not CompareMem(pointer(fHeaderB64), tok, headerlen) then
exit;
I suspect that fHeaderB64 is created with the following "template" in mind:
if fHeader = '' then
FormatUtf8('{"alg":"%","typ":"JWT"}', [aAlgorithm], fHeader);
Any idea what would be a recommended course of action for me here?
Thanks!
Works for both Win32 and Win64.
THandle is defined as following in System.pas
THandle = NativeUInt;
which I guess explains the problem with -1 as an initial value.
In case it is of interest to someone:
Software version tested: 2.1.5802 (2023-08-30 09:00:57)
Windows 10 64bit (10.0.19045) [WinAnsi 15.8GB 4A651701]
4 x Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz 4MB cache (x86)
on LENOVO 20J4000XMX ThinkPad L470
Using mORMot 2.1.5802
TSqlite3LibraryStatic 3.42.0 with internal MM
Generated with: Delphi 12 Next 32 bit Win compiler
Time elapsed for all tests: 4m04
Total assertions failed for all test suits: 0 / 77,927,545
! All tests passed successfully.
Software version tested: 2.1.5802 (2023-08-30 09:16:02)
Windows 10 64bit (10.0.19045) [WinAnsi 15.8GB 4A651701]
4 x Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz 4MB cache (x64)
on LENOVO 20J4000XMX ThinkPad L470
Using mORMot 2.1.5802
TSqlite3LibraryStatic 3.42.0 with internal MM
Generated with: Delphi 12 Next 64 bit Win compiler
Time elapsed for all tests: 4m21
Total assertions failed for all test suits: 0 / 77,892,415
! All tests passed successfully.
In order to compile mormot2tests I had to make a minor change in the mormot.net.sock.pas file on lines 4699 and 4721, changing:
Handle := {$ifdef FPC}THandle{$endif}(-1);
to
Handle := {$ifdef FPC}THandle{$endif}(0);
The original code raise the following error:
[dcc64 Error] mormot.net.sock.pas(4699): E1012 Constant expression violates subrange bounds
Not sure if my "fix" is the best one, but "it works"™
Thanks for making mORMOt a "future-proof" framework.
Pages: 1