I went with using Keycloak for a platform I'm developing right now and it feels like a very overcomplicated enterprise piece of software - it still does work and has the features that I need (notably: an SSO login portal, user registration, password resets and social login), but definitely needed a certain amount of time to configure correctly and had odd bugs, like me needing the following in my reverse proxy configuration:
otherwise connections would randomly drop. I was looking for other ways to make development a bit easier and also settled on mod_auth_openidc, which is an Apache module that lets it act like a Relying Party and handle lots of the heavy lifting (protecting endpoints, refreshing tokens etc.) for me, and lets me work with just a few headers that are passed to the protected resources: https://github.com/OpenIDC/mod_auth_openidc
It works, but I'm still not happy - I realize that there are many types of attacks that have historically been a problem and that certain OpenID Connect flows try to protect against, in addition to the fact that if I wrote my own security code it'd almost certainly be worse and have vulnerabilities (in the words of Eoin Woods: "Never invent security technology"), and it's a good thing to follow standards... but the whole thing is such a pain. Both OpenID Connect, Keycloak and configuring mod_auth_openidc.
Right now I'm moving permissions/roles back into the app DB, because I don't want to have to work with the Keycloak REST API every time I want to change what a user can or cannot do in the system, in addition to permissions which might only apply conditionally (one user might be related to multiple organizations, having different permissions in the context of each).
Regardless, it's nice that there are more pieces of software out there to choose from! Do manage your expectations when working with OpenID Connect, though.
What I've always wanted from a system like this is the ability to send a one-time registration link to someone over e-mail.
That would enable more controlled self registration without fully opening up registration.
I never found anything like this though. If anyone knows something please let me know.
Have you considered/tried Ory Kratos + Hydra [0]? I've never used either Ory or Keycloak, but out of these 2, Keycloak feels more opinionated and harder to set up, though it does have more features.
This is a unique feature of Kratos/Hydra, you can use your own frontend components. With many other implementations this is not possible.
What do you mean by "much more opinionated client", there is a set of standard flows that your app has to handle and thats it for most cases.
If you want out of the box components they also have a paid version for that (and code examples in OSS)
Having built and worked with a variety of oidc implementations. It is an incredibly misused technology, while it initially can be easy to integrate into your app. It increases the complexity of the app to a surprising degree. Now suddenly your little webapp have to handle how various devices handle redirects to external sites, receives callbacks. And all the weird ways oidc implementations uses cookies, handles return urls, logouts, profiles etc.
I am not so sure the model of using a central oidc solution as the primary login to your app is such a good idea. There are so many failure points in just getting to and fro the oidc portal that can break in all sorts of ways, with no good way of debugging, leaving users stranded in the middle of redirects. Especially as logs are split between 3 parties, the browser, the client (server) and the oidc server.
I ripped out our oidc primary login and implemented comparable features in my current company (this is probably not for everyone though), it has vastly reduced support tickets, and generally been a faster and more intuitive solution, but more expensive, and requires more domain knowledge. Still I'd rather have that than having a team spend years handling support tickets for endless social login issues.
If you choose to use oidc, please, please only use it for social logins, don't do oidc within oidc within oidc (I am not exaggerating, I've seen 5 levels of nested oidc and oauth2 flows). Like a lot of these solutions such as Zitadel, Auth0, etc. It becomes a nightmare to support and mature.
I’d agree that layers of OIDC should be an anti-pattern but aside from that my experience with OIDC (developing and running it in production) has been nothing short of amazing.
Before OIDC it we had (mostly) SAML but it is a beast by comparison and was limited to enterprise use.
The ability of being able to switch auth out with another identity provider with such ease has been nothing short of a blessing.
Yes some overuse redirects and do weird things but the social ones I’ve used plus Okta and my own home grown ones have all been fine.
MitID (national provider login) in Denmark, is about 2 layers of oidc in of itself (normal oidc and an oauth2). Plus whatever the consumers already have, which is often 1 or 2 as well. They're often used as a layer of abstraction which is a gross misuse of the technology.
As I mentioned previously using it for social logins by itself, is fine in most situations as they're quite mature. And IMO the best and probably intended use case of the technology and there it works quite well.
At the most basic yes, but the protocol doesn't describe what the login part is and how that works. Often it implements session using cookies, which given the state you were in previously. Maybe you wanted to embed the login page on your own site (iframe or webview), now the cookies are flagged as third party cookies and blocked in a variety of context.
Especially in an app context it becomes a minefield of half baked webview implementations, browser specific quirks, and limitations on how to call back to the host app which initiated the flow.
Other questions are how do we handle return urls, i.e. return to where we started the login flow from? there isn't a good answer in oidc, unless you use some of the more extreme flows. It becomes tricky to implement without opening yourself to open redirect attacks, which kind of voids the benefits of oidc (that you don't have to handle the complexity of the authentication).
Also there are endless variations of the oidc flow, the most common being code flow, which is pretty much what you describe. But it gets increasingly complex as you have to handle native app login (PKCE pronounced pixie). Using these flows you end up becoming as much an expert in the technology as you would've been just implementing authentication and identity yourself.
> Using these flows you end up becoming as much an expert in the technology as you would've been just implementing authentication and identity yourself.
I mostly agree with this. The only thing I'd say is that Auth0 when I used it did abstract away at least the different flavours of Oauth2/OIDC, and we just coded against Auth0's implementation.
Which is a crazy situation to find ourselves in as an industry, but there we are.
That is probably also the best path if you choose to use oidc as a login / identity solution etc. They do give a lot of stuff out of the box, as well as making it quite easy to integrate with. But at quite the price =D
From my point of view the dangers are implementing parts of this protocol yourself (i.e. becoming one of the parts in the login chain), it requires a surprising amount work to mature, which is why relying on Auth0 which already has been through that is quite nice.
> Maybe you wanted to embed the login page on your own site (iframe or webview)
Half of the reason to use SSO is that users should not ever enter their credentials on arbitrary web sites.
Otherwise generally agree with the rest of your points. Acquiring a token from a web page and especially authentication from non browser contexts can be excruciatingly difficult. Imagine an idp only providing login through browser prompts, when you are trying to build a CLI that requires login.
You can easily end up nested flows if e.g, your app uses auth0 and the user is a business user whose company is saml federated to Azure, for example.
You can quickly get to 3 levels if e.g. your app uses auth0, github login is supported and then the user does social login to github etc.
2 or 3 levels of federation is common.
More levels are possible which is bad if you value your sanity but I think (well, hope) rare in practice. The way you get to 4 or 5 levels is if you have organisational dysfunction on top of all this and you are forced to do your logins thru e.g. one or more fed servers owned by a different team in your company (who add even more layers of indirection).
Mostly as a relying party you will be insulated from all the complexity but if you own your oidc server and manage the brokering you will probably have to deal with a lot of edge cases.
Yep for normal apps it is rare. The debugging sessions I've been in trying to untangle some of these flows gives me the shivers. Oops someone had a huawei with this specific default browser, that doesn't handle url paths?!?, some android webviews versions not handling redirects properly, android apps not being able to handle redirects in a webview if the app is not active.
These are very app specific, but that is just the amount of complexity that is opened up for in some of these flows. Hopefully webauthn / passkey can help reduce some of these. But I doubt it.
It should be yes, although I think what the parent was getting at was layers of OIDC where one provider redirects to another and then you get 2 redirects back.
I’ve seen it a few time and can only conclude it’s the work of amateurs.
It really is, in some of these flows the single sign on nature of oidc isn't even used, or hacked away. And only used for login. Which is absolutely wild.
I argue that the complexity you are describing is inherent in any solution where multi-level sessions are present-- whether the auth mechanisms is OIDC, SAML, or something bespoke. Beyond social logins, there are use cases where multi-level sessions are required. One example is delegating authentication to another IdP. It's possible to use a OIDC client and configure the IdP to not create a session if multi-level sessions are not required.
While I think auth is hard it is still doable without having to become an expert when it comes to the details. I recently played around with oauth2proxy and nginx and got it working: https://github.com/layandreas/oauth-proxy-example
It indeed isn't that hard to get something up and running with oidc or oauth.
However, what becomes problematic is handling inherent complexity of whatever the provider you use is. If the OIDC flow is only intended for you or in-house at a company then it is less problematic. But when used by all sorts of people and devices, it will break in all sorts of problematic ways.
But that isn't to say that you shouldn't use the technology it is fantastic at what it does. I.e. handle social identities in the case of oidc, and authorization in the case of oauth
Not looking for your source code, what shape did your solution take? Does it single sign on? Single sign off? How do you convey permissions and groups? Is your app the source of truth, or do you read users and groups out of another IdP?
If login/Single Sign On is what you are after you are arguably better off with Central Authentication Service (CAS). It is much simpler. Unfortunately it isn't as widely known or popular.
Yep, this is why I say that oidc is vastly misused. There are much better options out there for implementing good solid, login, session flows. Using oidc as the only tool in the toolbox is a recipe for disaster.
Because the CAS protocol is deprecated? It's arguable simpler and easier to deal with and works really well, but not that well supported and that isn't likely do improve at the protocol won't evolve any future.
We're currently in the process of migrating from CAS to OIDC and so far the server side hasn't been much of an issue, but compared to CAS the clients are a little hit and miss. Authentication always works, but claims are annoying.
It has been written with keycloak as the auth server but should work for any proper openid connect implementation since I used the specification as a guide.
I would like to become more knowledgeable about authentication and identification tech stacks (LDAP, OIDC, Oauth, CAS, etc.) and have hands-on experience. I already dabbled a bit with some LDAP, I have professional experience in administering linux boxes and intranet infrastructure. Where should I begin if I want to set up a simple homelab with maybe a raspberry and some NUC ?
Take a historical journey by setting up an LDAP server like OpenLDAP or Samba, add Keycloak on it (or just use Keycloak for LDAP too), then integrate it to AWS using SAML and Google using OIDC.
Oidc and keycloak have been great for my project. We stear users to it as it also allows for user impersonation by an admin. Thi is a huge help to debug issues for users, while also keeping any authentication work out of our app and the concern oof the authentication layer.
This alone sets it apart for us. Lots of other solutions don’t offer this. And then users make requests to our software for this ability and like I tell them, there’s no way our software is going to insert itself into your authentication system. That’s for your authentication system!!
Anyway, I seem to be the minority here but maybe that’s the domain I work in.
OpenID no, it's not. OpenID Connect (OIDC) which is built on top of OAuth2, yes, it's very much a thing and much easier to deal with than plain. OAuth2
The deeper you go into the topic the more you will discover. It's an ultimate "rabbit hole" - web, native, SPA flows, PKCE, JWT, session storage, custome middleware for your favorite flavor of backend framework, etc
It works, but I'm still not happy - I realize that there are many types of attacks that have historically been a problem and that certain OpenID Connect flows try to protect against, in addition to the fact that if I wrote my own security code it'd almost certainly be worse and have vulnerabilities (in the words of Eoin Woods: "Never invent security technology"), and it's a good thing to follow standards... but the whole thing is such a pain. Both OpenID Connect, Keycloak and configuring mod_auth_openidc.
Right now I'm moving permissions/roles back into the app DB, because I don't want to have to work with the Keycloak REST API every time I want to change what a user can or cannot do in the system, in addition to permissions which might only apply conditionally (one user might be related to multiple organizations, having different permissions in the context of each).
Regardless, it's nice that there are more pieces of software out there to choose from! Do manage your expectations when working with OpenID Connect, though.