1

I have an app that is written with FastAPI and SvelteKit, both these is running in separate containers, the current solution is Svelte sends the username and password to the FastAPI server, the FastAPI server then returns a signed JWT to svelte which is used to authenticate with FastAPI.

Heres the login flow Svelte -> username + password -> FastAPI

FastAPI -> JWT -> Svelte(stored in cookie)

Here's what happens when a request is made Svelte(Authorization: Bearer) -> FastAPI

I want to get rid of my own username and password and use KeyCloak for my authentication. I'm super new to OAuth so I have no idea what I'm supposed to do or even what terms to search.

Here's what I understand I want: Svelte(goto "/login") -> redirects to keycloak -> login and get a token (somehow get the token to FastAPI so I can sign my own token and send it to svelte)

And when I make a request Svelte -> FastAPI Token -> FastAPI

MaoMaoCake
  • 27
  • 4
  • Have you seen https://stackoverflow.com/questions/54884938/generate-jwt-token-in-keycloak-and-get-public-key-to-verify-the-jwt-token-on-a-t ? – MatsLindh Aug 17 '23 at 13:03
  • @MatsLindh Interesting but I'm still a bit confused, what you are saying is that I should login from the frontend get the token then store. and when I make a request FastAPI shoud be the one verifying the token? – MaoMaoCake Aug 17 '23 at 13:12
  • 1
    Yes, that's how the exchange usually happens with JWTs - keycloak signes the token, you then verify that the token was properly signed in your backend server. FastAPI will have to verify the token in either case; that way you trust the token signed på keycloak (and if you need to, you can verify with keycloak from FastAPI that the token is still valid and hasn't been revoked/user deactivated/etc.). – MatsLindh Aug 17 '23 at 13:13
  • Thanks, I saw something about the tokens expiring every 5 mins so do I have to constantly keep refreshing the token? – MaoMaoCake Aug 17 '23 at 13:16
  • Yes, if you're going with a JWT that you don't explicitly verify that the user is still valid for on the FastAPI side, then those five minutes is the maximum time that will elapse before the user is no longer logged in. – MatsLindh Aug 17 '23 at 15:25

2 Answers2

0

The easiest way to add Keycloak authentication to an app is oauth2-proxy. oauth2-proxy stands in front of your application like a reverse proxy and it'll handle all the OAuth2 bits for you. oauth2-proxy will then generate the sign-in URL to Keycloak (/realms/{realm-name}/protocol/openid-connect/auth) with the appropriate parameters to start an OAuth2 sign in process and set it to redirect back to the application page, Keycloak will display sign-in page, then after the user completed their sign in, it'll redirect back to the application, at which point oauth2-proxy will check the JWT token are valid, set a cookie, and then pass along the username, access token, and ID token to the server as HTTP headers to the proxied request.

When using a oauth2-proxy kind of approach, neither your Svelte frontend app or FastAPI app needs to know anything about OIDC/OAuth2, they don't even need access to the client secret, which reduces the chance of your application leaking those secrets. The application may need to be able to decode a JWT token to read Access token and ID token (which contains the auth claims), but if all you need is just a Keycloak validated username/email, then your FastAPI app can just read the HTTP headers with Header() to get the username. Decoding JWT without signature verification (because we assume that oauth2-proxy already validated the signature) is pretty simple to implement with just standard library, it's basically just a couple string manipulation, base64, and json parsing.

Alternatively, you can implement OAuth2 flow directly in your application. Direct integration may be necessary if the application needs to do things that are more complicated than just basic authentication and authorisation with the JWT tokens or if you want finer control over the auth process. Keycloak supports OAuth2 via OIDC, so you can use any OIDC library like pyoidc or with a Keycloak specific integration like fastapi-keycloak-middleware. Implementing OAuth2 without OIDC is also possible but it will be much more involved. Keycloak, OIDC, and OAuth2 all has a lot of configuration involved to support various different use cases and security requirements, you'll need to look into these configurations in more detail to figure out which suits your requirement.

Implementing all this without using an OIDC and/or OAuth2 libraries is possible, but I wouldn't really recommend them. You'll just end up reading a lot of boring OAuth2 and OIDC specs.

Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
0

its me again, here's a conclusion for those who come across this thread in the future. I've decided to go with the official keycloak.js connector for my app and the keycloak python lib to verify the token on the backend.

MaoMaoCake
  • 27
  • 4
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 30 '23 at 19:13