Implementing TOTP

To avoid reinventing the wheel, has anyone implemented, or seen it implemented anywhere else, a complete TOTP authentication implementation (preferably in Delphi), from enrolling users with QR codes, secret storage, code validation, etc.? Hopefully also complete with a Windows Service, or some ASP/JSP/PHP back-end? - all the components are generally available, it’s just rolling it all into a complete product that would take time I’m trying to save. There are a few mobile apps that can be freely used for the client side, which seems like a good motivation to piggy back on that.

Haven’t done anything with it… but I have previously stared it on github.

While it still doesn’t have one-time password mechanism for login (it’s in the roadmap), TMS Sphinx is a full OAuth complaint authentication/identity server for Single Sign-On, written in Delphi:

Geoff,

Thanks, but I was looking for server-side. Client-side there are already free Microsoft/Google/Authy Authenticator apps, which we do not need to maintain.

Alex

Wagner,

Yeah, it really needs it. Or something else, or both and more.

If it generated & stored the secret by itself, plus produced QR codes to enrol (and validate) users, then had configuration to force 2FA per user and also did the extra prompt, it would have been 10 times more useful.

Conceivably, all that can be added, but then I would use IntraWeb instead and add it there – it gives me a webserver with all the GUI I need already.

Alex

It’s in the roadmap and will be implemented in near future, all the features you mentioned.

I respectfully disagree. Sphinx does a lot of things, for many different use-case scenarios, and it’s being used in production by many customers, including myself, actually.

It adds a lot of things compared to a raw Intraweb application.

Wagner,

Ok, thanks, point taken.

I’d be interested to see any/some/all of the different use-case scenarios where it’s actually being used. That would give us a lot of ideas. Can you publish anything along these lines, please?

Alex

Here are two sites I used:

With that code, it’s all pretty easy. It was harder for me to plug that in the middle of what I had, including secret storage, display and user prompt/input/error handling.

And so, coming back to TMS Sphinx, as I already have a whole application in IntraWeb, adding this one bit was obviously easier than starting from scratch with Sphinx. On the other hand, if I could get more out of Sphinx right out of the box (plus knew more about the satellite products, because Sphinx alone is really not self-sufficient in Applications space), I may have taken that path instead.

Alex

In my personal case, the sites and apps are in Portuguese, but you can have an idea. Both of these sites have a “customer area” that needs a login, and both use TMS Sphinx behind the curtains:

https://www.validadortiss.com.br (click “Área do cliente”)

https://www.nuvemfiscal.com.br (click “Comece grátis”)

In both cases above, the use case is single sign-on, i.e., users can login to a separate Sphinx server and then have access to all your systems, be it web application, desktop, etc.

Another simpler use case is TMS Smart Setup itself, where we use Sphinx to handle authentication for TMS customers to download the products. It leverages the login to the normal TMS site (which doesn’t use Sphinx since it’s been there for years), but then manages the tokens and access to the Smart Setup repository from it. This is more a “machine-to-machine” use case.

Ok, it allows the users to self-register and validates the email, but that email can be a 10-minute one, so it would need to be cross-checked against some other database. Then there’s no way to change a password in Sphinx, if I recall correctly. And I could not make it send me JWT or SAML in POST, so the server can see it, the last time I tried. Plus of course there’s no way to group the users, no way to give different users different access rights, or manage them on the server-side, nor do 2FA as we are discussing now. So, I was missing a few features to make it work for me and to roll out these features (some may not even be possible without support in the core, like grouping, access rights, JWT or SAML, etc.) would be doable but laborious, so it’s a trade-off between what you get out of the box vs. what else you need to add. And the more is in the box, the better the deal. For my use case, it didn’t pan out. I liked what I saw, and I’m still keen to come back to that, just need more features there to make it worth my while.

You mentioned SSO, how do you do it here? – if you cannot send JWT to the server (except in a fragment, where it’s not visible), how can the other server know who you are? Are they all using the same database?

Mind you, I only scratched the surface in Sphinx, but it did cost me a few days of trial & error and just generally, exactly how much time can one invest up-front is always limited.

Alex

You can use the user e-mail for many things, like notifications, confirmations. That’s how most of current login systems work. And actually the e-mail is also used for…

…change user password. It is possible, not sure why you say it isn’t.

I’m not sure what do you mean by this.

Why not? You can extend the users by adding any information you want to them. Some people asked this in our support forums.

JWT can be signed with a private key, and the server can make the public key available. So API servers consuming JWT can check if the JWT is properly signed by the server using the public key, and then check if the issuer and audience are properly set and valid.

Wagner, appreciate your responses. I’ll reply in order:

  • Email: if the registration was done with a 10-minute email address, then the user is still accepted as a valid account with access & all. This needs more control. For most companies, it will have to be their corporate addresses, so somehow this will need to be enforced. Then a single message validation would not catch 10-minute addresses, so the user should be denied access for a while, until that can be sorted. And emailing codes is not especially secure, so I’d rather not (and if I must, I already can anyway, so no immediate benefits there).

  • Not as a “change password” functionality, but only as “I forgot my password, please reset it” - a bit clumsy. It’s really not at all the same.

  • I mean that when you add an application (which BTW has to be done programmatically now, which is a bit clumsy too) with implicit flow, a redirect and JWT, it places the token in a fragment of the redirected URL, which hides it from the server, so the server never receives it. All cloud IdP’s allow for these codes to be POST’ed, where the server can pick them up and do just as you described. If the server cannot see the token, it’s unusable for my use case. It can instead use code flow, but I was trying to avoid that, because it complicates things, even though it could be somewhat more secure. It also does not have built-in support for RS256 signed tokens, although it was reasonable easy to implement as an extension (mostly because I have encountered that before, not because it was really straight forward per se - it would surely prove to be a challenge for anyone new), so I’m not fussed about that.

  • Yes, you can extend, correct. And you already have “roles” and “user_roles” tables, but these remain un-populated. As is “tenant” field. And I’m not really sure how to handle any of this: are we supposed to add a direct DB connector and manipulate that concurrently with what Sphinx does automatically under the hood? Or would there be any conflicts? I’m inclined to leave Ceasar’s to Ceasar and not interfere in the internal workings, but then all that should be somehow exposed by Sphinx, so it can be manipulated from the client/caller’s side. So, how should I create a “role”? And how can I assign users to roles and re-assign/remove them? And check user’s role programmatically at signon to enforce any permissions? - the permissions would then need to be defined, maintained and used from a different database as well, I guess.

  • Again, as per above, with implicit flow, it’s not doable: the server never sees the token. You need to add a POST option for this. It cannot be added from our code, as far as I could see. And yes, I know about the authorization code flow, but I’d like to avoid that.

BTW, TMS has never explicitly announced the timetable for implementing enhancements. Is it being planned? What’s the ETA, do you already know? - I’ll give that another try when it arrives…

That depends on each application. You can enforce the e-mails you want, Sphinx is not closed-source, that’s one reason to choose it over Auth0 or Identity Server, for instance. It’s Delphi, do what you want. If you just want to accept corporate e-mails, so be it. I fail to see how this is important in most applications, user is creating an account for himself, if he uses a 10-minute e-mail, he will eventually lose access to his account. If you give super powers to him just by creating an account and that’s a problem, maybe you can review that as well. And what would be the alternative to e-mailing code?

Change password is possible from code. You can implement the UI yourself, for now, until (and if) we add it to Sphinx., You will have to do it anyway without it.

Your case it very specific, I remember it now. Yes, we will implement sending codes via form post, although that is not OAuth specification, just an extension. Implicit flow is not recommended anymore and authorization code is more secure. It’s interesting that you are worried about a non-corporate e-mail but accepts an unsecured authorization flow. But yes, implicit flow is sent via fragment in the URL (OAuth standard), we plan to add sending token via form post (OAuth extension) and we recommend using authorization code flow with PKCE (which you specifically don’t want or can’t use).

I’m not sure what do you mean by that. All my Sphinx servers use RS256 signed tokens. Sphinx is a Delphi library, not a close-source tool. It’s not a cryptography library, if that’s what you mean, but you can use any one available there, either open source or licensed (like TMS Cryptography Pack) or OpenSSL.

It’s up to you. Sphinx was designed to have user data extensible, I linked to it in a post above. That’s how you integrate with your application and simply add data that Sphinx doesn’t have yet - and some that it will never will. Add any fields, roles, permissions, data, internal ids, whatever you want. Sphinx is the boilerplate, use what it has, extend and implement what it doesn’t have.