How to SECURE My Microservices Architecture (REACTJS + SPRING CLOUD GATEWAY) With Keycloak

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I have a React front end  connected to a Keycloak server.   I click on the login button and I'm redirected  to the Keycloak login form. Now, I can call my   microservices architecture to read the protected  data behind a Spring Gateway application. Here it   is. The OAuth2 protocol has different behaviors  depending on the client's used. But I can't use   the same workflow for the backend authentication  then from the front-end authentication. Let's see   in details. I have a backend server which requires  to access protected data. But this protected data   is behind an OAuth2 authorization server. When the  backend tries to access the protected resources,   it will receive a login page. I must show this  login page to the final user. Once authenticated,   the backend can access the protected resources.  Until here, it's okay. I've already done a video   about that. Check the link in the corner. But the  front end can't have the same workflow. Let's see   why. Let's go back to the initial step, when the  authorization server returns the login page from   the backend. The authorization server returns a  login form because it already knows the backend,   because it already trusts the back end. How to  create this trust? I first need to register my   backend in the authorization server. Then, the  authorization server returns me a client_id and   a client_secret. I must store them in the backend.  I need those two keys to talk to the authorization   server. But what if I change my backend to a front  end. I can't store the client_id and secret in the   front end. As the user will download the front  end in the browser. Anyone could read those   keys. The previous workflow is the authorization  code flow. But when using public clients, like a   React application or a mobile application, I need  another layer, I need the PKCE authorization code   flow. PKCE stands for Proof Key Code Enhanced  authorization code flow. Now, while registering   my client in Keycloak, I indicate a hashing  algorithm. When starting the communication,   the front end will create a random string as  a code verifier. The front end will encode the   code verifier and send it to Keycloak when first  asking for the login page. Keyclock will decode it   and store the original code verifier. If the  login is successful, the front end must ask   again for the access token. And this time the  front end must send to original code verifier.   Keycloak will check if it's ok and respond with  the access token. The front end can use now the   access token to request the protected resources.  Why it is secure now? Because it's Keycloak which   request the callback. So, even if I try to send  a request by my own, with the client_id and the   encoded code verifier, I won't have the call  back to my application. And I won't receive   the access token. Ok. So, what must I change in  my application now? The resources server still   need to connect to Keycloak to validate the  access token received from the request. The   API Gateway needs no more OAuth2 configuration.  All is moved to the front end. For the front end,   I can call the specific endpoints of Keycloak  manually. But I would rather use a library for   that. And finally in Keycloak, I must register  my front end as a public client, with PKCE.   Let's see it. I start with the project used in my  previous video, where I connect the API Gateway   with Keycloak. As said I need the configuration  to connect my resources server with Keycloak. I indicate the URL of Keycloak.  And in the security configuration   I indicate which scopes are necessary  for each endpoint. And the controller   stays simple. I need no more OAuth2  configuration. Let's go now with the API   Gateway. Here, I need to remove all the security  configuration, as I move it to the front end. Now, as I have a front end  connected to the API Gateway,   I need to configure the CORS  to avoid the usual problems. That's all. API Gateway clean. Let's move to  Keycloak. Let's create now my front-end client. I leave those options disabled. The client  authentication off means that the client is   a public server. If I enable it, I will  get a client_id and a client_secret. And   I don't want a secret. The authorization is  for fine-tuned authorization. I don't need   this. I leave the rest of the options. The only  one which interests me is the standard flow. I will now add the callback URL This is the one which will make  the second request automatically.   And I must add the web origins to  allow my front-end access Keycloak. Let's go now to the advanced settings. If I scroll down, I can  see the PKCE configuration. I choose the algorithm to use   and that's all. Finally, I create  my scope and add it to my client. That's all. Let's finish with the front end.   As said I can do it all by requesting  the Keycloak endpoint, but it's a lot   of hard coding and there are some libraries  which will do it for me. Let's use this one. Wait, wait oidc or OAuth2? The OAuth2 is the  original authentication Protocol. And oidc or   Open ID Connect is a layer over OAuth2. oidc  allows me to get all the necessary information   at once. This way I avoid requesting Keycloak  each time I need to read protected resources.   I have already created a front-end application.  I wrap all in a component called App. Here is   the Header component. And this is the  AppContent component. Then I have the   Toaster component. Which are the popins  which display some temporary information.   It's another library I use. I have then  the Buttons component which wraps those   buttons. And finally the AuthContent component.  I don't see it now because I'm not authenticated.   All I need is to create two helpers. One  to talk with Keycloak and the order to   talk with the backend. Let's start with the  authentication helper, to talk with Keycloak. This is the URL of Keycloak. The client_id I've configured in Keycloak. The callback URL I've configured in Keycloak. This is to request the access token. I  don't want a cookie or something else. Here, I must specify the scope I want: the open ID  and the profile as I want to display the username This first method is to read the user  object stored in the local storage. This   method doesn't read it from Keycloak.  I must first log in to use this method. This will perform the login. It will redirect  the end user to the login page of Keycloak. Finally, the logout method.   All those methods are already connected to the  buttons. Let's see what I do in the callback page. Here, I only call the signinRedirectCallback,  which will receive the user object and store   it in the local storage. This way, it's  accessible for further requests. Let's   continue with helper to talk with the back end,  which is using axios but with the access token. When calling the backend, I need the access token.   This access token is the JWT to use  in the HTTP header of the requests. I only call the backend if I've already logged  my user, if I've already an access token. Let's   see now how it works. When I click on the login  button, I'm redirected to the Keycloak login page. Here is the endpoint which returns  me the Keycloak login page. It contains the client_id, the redirect URL,   the scopes and the code challenge,  which is the encoded code verifier. When logged correctly, I have the sign in  callback, I have the callback URL which   is called. And I have the user loaded in my  local storage. Now, I can call the back end   which returns me to protected resources. In the  back end request I can see now the access token   sent in the Authorization Header. Okay, let's  make a quick recap. I've removed the configuration   from the API Gateway. I've connected my resource  server to Keycloak. I've created a public client   with PKCE in Keycloak. I've added the library  oidc-client to my front end. I've configured my   oidc object with the client_id, the Keycloak  URL, the callback URL and the scopes. After   logging for the first time, I've used the received  access token for all the requests to the back end.   That's all for this video. I've also done other  videos about the OAuth2 protocol, as a backend   server alone, with Keycloak, with GitHub connect,  or with a simple JWT. Feel free to watch them   all. And of course, click on the like button and  subscribe to my channel. And see you soon. Bye!
Info
Channel: The Dev World - by Sergio Lema
Views: 13,988
Rating: undefined out of 5
Keywords: java, keycloak, react, spring security, api gateway, How to SECURE My Microservices Architecture (REACTJS + SPRING CLOUD GATEWAY) With Keycloak
Id: hfeOqvHxHO8
Channel Id: undefined
Length: 14min 19sec (859 seconds)
Published: Mon Feb 06 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.