Showing posts with label Object Pascal. Show all posts
Showing posts with label Object Pascal. Show all posts

Monday, 24 February 2025

IAM Cloak, without the Dagger

 - or using a Keycloak setup as your Authentication solution in your native Delphi application.



With no reference to melodramatic intrigues, espionage, secret agents or a Marvel crime-fighting team involving experimental drugs, this post will just try to enlighten how fairly easy it is to get started with Keycloak as an authentication backend for your Delphi application.

This post is a continuation of some earlier post about IAM related stuff and my Auth component samples for PingOne, EntraID and now Keycloak on GitHub.

The posts can be found here:

GitHub gist/repos:
The EntraIDAuth was used in my Delphi Summit 2024 session: I can, therefore IAM.

Keycloak

Keycloak is a mature Open Source IAM solution, and I am by not means an expert - but I have been dabbling with some of the other provides - and this is as good as any.

The easiest way to get started is to install a docker container as described in the official documentation here.

There are other options and a lot more to it, but that short guide has you started, and we use that sample as the basis for the KeycloakAuth component, found in the last repo link above. Note that at the time of writing this post, it does only parse an access token for the "uniqueid", and the state parameter is by default added.

The state value is a GUID (or should I say UUID) - so to get "proper" UUID, I end up doing this:

if FUseState then
begin
  FStateValue := TGUID.NewGuid;
  URL := URL + '&state=' + GUIDToString(FStateValue).Trim(['{','}']).ToLower;
end;

Using the state parameter in the authorization code flow, helps to check that the client value sent matches the value in the response - to mitigate CSRF/XSRF (Cross-site request forgery) attacks. After that initial check one should then check the nonce given within the id_token.

But getting ahead of myself - to use and play around with my KeycloakAuth component - get it from GitHub as mentioned above - and install the component in the IDE (Delphi 12 package in repo).

As any of my other Auth components, this is based of TWebBrowser - and I hear you ask why not TEdgeBrowser? Well I had done some things similar years back before Edge was a thing, but since I do strongly suggest that the "SelectedEngine" property is set to "EdgeOnly" - TWebBrowser does internally use a TEdgeBrowser. It does mean you do need to install the Edge WebView2 SDK, and deploy the correct dll. Read all about it here.

Create a new VCL application and drop a KeycloakAuth component, align to client and set the following properties:

    RealmName = 'myrealm'
    AuthPath = 'http://localhost:8080/realms/'
    ClientId = 'myclient'
    RedirectUri = 'http://localhost:1234'
    AuthEndpoint = '/protocol/openid-connect/auth'
    TokenEndpoint = '/protocol/openid-connect/token'
    Scope = 'openid'
    UseState = False
    ResponseType = 'code'
    UserIdClaim = sub
    OnAuthenticated = KeycloakAuthenticated
    OnDenied = KeycloakDenied

Add an OnAuthenticated and OnDenied - like:

procedure TForm6.KeycloakAuthenticated(Sender: TObject);
begin
  ShowMessage('Welcome '+KeycloakAuth1.GreetName+'!'+
    sLineBreak+sLineBreak+'You have been authenticated as userId:'+
    KeycloakAuth1.UserId);
end;

procedure TForm6.KeycloakDenied(Sender: TObject);
begin
  ShowMessage('You have not been authenticated!');
end;

In the forms FormShow event call the components Authorize procedure, to start the flow.

I will add more capabilities to the component - such as nonce and code challenge, and cover all OpenID Connect response_type combinations.

To get a good grasp and overview of the OpenID Connect flows - take a look at this Medium post.

Happy 30th anniversary - Delphi! and see you at Delphi Summit 2025.

/Enjoy

Saturday, 28 November 2020

A Set back?

- or how could I forget some set operators.


Recently a colleague of mine asked me to review some old code, and a line similar to the one below pop into my view as strange:

if (doorStates * [dsClosed, dsUnlocked] <> []) then

It had been so many years since I had used that specific syntax, that I completely forgot about some of the set operators in Pascal and Delphi - so I thought I would write up a small post on Sets in Pascal/Delphi.

In regards to the silly doorStates example above - here is a little riddle: When is a door not a door?

Wednesday, 9 December 2015

Why "browser" clients not always are a good idea

- or why you could/should consider a n-tier setup, spiced up with a briefcase model - part nil.

I haven't really been able to see the revelation in browser clients - and I am not quite sure why anyone would always consider this as a good option.

It might look tempting from an IT operations standpoint and maybe also from a management view - but would they have a chance to know - it is the users experience and productivity that counts - and that is what we all should care about.

So I would say that if the job the client needs to handle is comparable to an old VT100 dumb terminal - then browser it is.


Thursday, 21 August 2014

Introducing the REST Debugger....

- or How I helped a friend make his first REST client.

A good friend of mine, had finally decided to do some REAL programming :-D - and had for that purpose purchased a Delphi XE6 - and being relative new to the environment and hadn't looked into Delphi since version 7 - it is my privilege to help him getting started.

I had hoped for a "hello world" scenario, but he actually wanted to try to start off with a REST client against something like Google Translate.


Sunday, 22 June 2014

Using Google Chromecast from Delphi desktop application

I have done a small example of a desktop application, starting the YouTube app on the Chromecast device and playing a video on your TV. Using some Indy components and a couple of the new REST components that came with XE6. Not bothering with the API's from Google.


This example does not really have any real life usage - since installing Google cast in your Chrome browser or using the YouTube app on your phone would make more sense. So unless you for some reason don't use Chrome as a browser or do not have an iOS or Android phone, this example is not that useful - but it shows the concept.

And I think that the Chromecast is a nice $30 device, that like "almost" anything else can be accessed from Delphi :-D (Update: I might end up using Mozilla's cast device, if the rumors are true - see update at the end of post).

Wednesday, 7 May 2014

Back'n'Front App - dual camera "fun"

Two weeks ago there was an App mentioned in a local newspaper - which, apparently, had done pretty well and which now is available also on Android. The app was described as taking 2 photos - one with the front camera and one with the back camera of your phone - and then enabling you to share the result with the rest of the world. How hard could it be to build one yourself?

Monday, 21 April 2014

Fun with Delphi XE6 App tethering and barcodes

Updated: Removed broken GDrive links, now linking to old GitHub repo.

One of the new key features in XE6 is what Embarcadero has chosen to call App Tethering components - the only problem I initially had with the name was that it implied that mobile had to be involved in some way - which is not the case. You can make a windows service that is a "receiver" from a desktop application running on the same sub-net.

An example could be POS systems, running on various devices talking to the same receiver - without bothering about implementing multiple communications protocols - these components all wraps this up nicely.

I wanted to give these new component a try, by making a very simple barcode scanner using my phone as the barcode scanner and then have the receiver send the barcode to whatever application was active.

A word of warning: this is a prof of concept - not ready for production or deployment - you need to do some work yourself to make it fit your needs. I have tried to use as little code as possible - leaving out all exception handling :-).