7 ms·
> In Keycloak nothing made sense to me until I got myself familiar with OAuth 2.0 and OpenID Connect. Hot take: OAuth2 is a really shitty protocol. It is one
by Perseids 4y ago
> In Keycloak nothing made sense to me until I got myself familiar with OAuth 2.0 and OpenID Connect.
Hot take: OAuth2 is a really shitty protocol. It is one of those technologies that get a lot of good press, because it enables you to do stuff you wouldn't be able to do in standardized manner without resorting to abysmal alternatives (SAML in this case). And because of that it shines in comparison. But looking at it from a secure protocol design perspective it is riddled with accidental complexity producing unnecessary footguns.
The main culprit is the idea to transfer security critical data over URLs. IIUC this was done to reduce state on the involved servers, but that advantage has completely vanished, if you follow today's best practices to use the PKCE, state and nonce parameter (together with the authorization code flow). And more than half of the attacks you need to prevent or mitigate with the modern extensions to the original OAuth concepts are possible because grabbing data from URLs is so easy: An attacker can trick you to use a malicious redirect URL? Lock down the possible redirects with an explicitly managed URL allow-list. URLs can be cached and later accessed by malicious parties? Don't transmit the main secret (bearer token) via URL parameters, but instead transmit an authorization code which you can exchange (exactly) once for the real bearer token. A malicious app can register your URL schema in your smartphone OS? Add PKCE via server-side state to prove that the second request is really from the same party as the first request...
It could have been so simple (see [1] for the OAuth2 roles): The client (third party application) opens a session at the authorization server, detailing the requested rights and scopes. The authorization server returns two random IDs – a public session identifier, and a secret session identifier for the client – and stores everything in the database. The client directs the user (resource owner) to the authorization server giving them the public session identifier (thus the user and possible attackers only ever have the possibility to see the public session identifier). The authorization server uses the public session identifier to look up all the details of the session (requested rights and scopes and who wants access) and presents that to the user (resource owner) for approval. When that is given, the user is directed back to the client carrying only the public session identifier (potentially not even that is necessary, if the user can be identified via cookies), and the client can fetch the bearer token from the authorization server using the secret session identifier. That would be so much easier...
Alas, we are stuck with OAuth2 for historic reasons.
[1] https://aaronparecki.com/oauth-2-simplified/#roles https://aaronparecki.com/oauth-2-simplified/#roles
- e1g 4y agoYou're right about the complexity and the steep learning curve, but there's hope that OAuth 2.1 will simplify this mess by forcing almost everyone to use a simple setup: authorization code + PKCE + dPoP. No "implicit flow" madness. Another big problem with OAuth is the lack of quality client/server libraries. For example, in JS/Node, there's just one lone hero (https://github.com/panva https://github.com/panva) doing great work against an army of rubbish JWT/OAuth libs.
- littlecranky67 4y agoThe problem with the authorization code flow is, it was not build with SPAs in mind. I.e. you always need a server-side component that obtains those tokens. So a 100% client/FE solution based on NextJS/React/angular/vue etc. can not simply be deployed to a CDN and then use Auth0/AWS Cognito/Azure AD whatever without running and hosting your own server-side component.
- zmxz 4y agoSPA is HTML/JS served by the server. We don't need client-only solutions. We need devs to understand how HTTP and browsers work. It means that we simply keep using what actually works, i.e. serverside component that obtains authorization and we use simple mechanisms to ensure token stays at the server and FE speaks to the server which in turn speaks to the target app. Proxying is not that difficult of a problem and we don't have to run in circles, inventing different flows only to cater to devs who can't learn their field.
- spion 4y agoYou've misidentified the problem. We need CDN solutions for front-ends because that's the best way to deliver great, scalable performance for complex SPAs. We also need a purely client-side flow for mobile (native) apps. Additionally, the authorization code flow (with PKCE) in Keycloak still supports pure client side authorization. Its more complex than the implicit flow, but it doesn't really matter as any library (including keycloak-js) will take care to ensure its done correctly.