 Hi, welcome to another Dev Nation Live, I'm Adsonia Naga and I'll be your host today. And I'm very happy to have my dear friend Sebastian Blanc today to present something cloud native and how can you secure your microservices. So Sebi, thank you very much for joining us directly from the beautiful city of Nice in the south of France. Sebi, the stage is yours. Thank you a lot, Adson. It's an honor to be introduced by you. And I'm really happy to give this session, it's always special to give a live session like this. Especially, I would like to thank first my daughter because I had a huge laptop issue and she borrowed her laptop, so I had to install everything on that. It's working perfectly, so it will be fun. Today we're going to talk about security. It's really short 30 minutes. I hope to show you a lot, not so many slides, a lot of live coding. I tried to cover many use cases and then we will have time for questions. So let's switch to my screen share now and here we go. Let me share, let me go to my slides. Okay, so let me talk a bit about security and more specifically about how you can secure your microservices in a cloud-native environment. Yeah, that is a lot of buzzwords, okay? We're going to use Keycloak for that. So I haven't time today to give you the whole big picture of what Keycloak is, but Keycloak is an identity user management server. So basically, it takes care for you of all your user management, your authentication flows, your authorization flows. You don't have to care about that anymore because Keycloak does that for you. You downloaded, you unzip it, you start it, you put some configuration and then you can secure your web apps, your backend sources and let's focus on that today because in a cloud-native environment you could have, well, let's say a Spring Boot microservice deployed, a service, a Node.js service deployed, a Quarkus app deployed, maybe even go microservice. And all these different technologies, you want to secure them in an easy way. And with Keycloak, it's possible to do that in an easy way. So basically, how does Keycloak work? Keycloak is based, it's using heavily the OpenID Connect protocol, so most of the time you access your web application and that is where you will log in to the Keycloak server to obtain a token and with this token you will be able to make a request to different services. When you get a token, and we won't spend too much time on this part because it's not really the topic, but once you log in in your web app, Keycloak will give you back free tokens, the ID token, which is a bit like your identity card, but then also an access token and that is the token that you will use to make secure requests to other services. This access token has a really short lifespan, around five minutes by default. And that's why Keycloak also gives you a refresh token that you can use to obtain a fresh access token. If we look at a monolithic application, I go to my server-side application, for instance, on my browser, and then I want to authenticate, I'm redirected back to the Keycloak where I enter my credentials and then there's the all off-float happening. Let's not spend time on that, but if everything is okay, the tokens are getting back to the web app. And then with this token, you can make some request to any services. So how does that work? So you can see here on the spectrum, the user has logged into his application and now he has an access token. This token, by the way, is a jot. We'd say that for JSON web token. That means it's a token that contains payload. It's a self-contained token. And with this token, it can call any service. And the service will receive the request and it will verify the token. And if it's okay, you can go on with the request. So what is exactly verifying a token? When your service receives a token, it will verify the signature, because when you obtain a token, it has been signed by Keycloak. Keycloak has a private key that you use to sign your token and your service has access to the public key. With that public key, it can verify the token. There are two ways to do that. One way is doing it offline. That means that when your service starts up, the first time it will retrieve the public key and then it can just verify your tokens without asking again Keycloak. But if you are in a less trusted environment, you can also ask your service to always ask Keycloak to verify the token. But be aware, if you do that and that you have a lot of requests, there will be a lot of requests to your Keycloak server. In most of the cases, the offline signature verification should be enough. Okay, that is for one service. But what if your service needs to call another service? That's what we see here. Well, that's the nice thing with this access token, service A, once you have verified your token, it can use the same token to call service B, for instance. And service B could be a completely different technology. Service B in its turn can also call a service C. And that is exactly what we are going to see now in the demo. I will have service A, which will be a Quarkus application. Service B will be a Node.js service. And a service C will be a PHP, yes, you heard as well, a PHP application protected by a state card proxy delivered by Keycloak called the Keycloak Gatekeeper. How do you make such a request? Let's see some simple codes and then we switch to some live coding, okay? So the first case, the most common case is once you have logged in to your application, you're in your web app and you want to call a service. So here's some JavaScript. How do you make a call with JavaScript? That's plain vanilla JavaScript. It's pretty easy, you start a new, you make a new agent request. And the only important thing here you see is in the third line, you have to set a header called authorization, and then the value is always bearer, space, Keycloak, token, your token, your access token, okay? Let's see another example. For instance, if you are in a Java application, this is more or less if you are in a servlet method, for instance, you are in your servlet method and you need to call another service, for instance. That's pretty easy with Keycloak adapters. You can obtain a Keycloak security context and from this context, you can obtain a token and then you just use any HTTP client that you want or REST client, doesn't matter, as long as you can put a header, okay? And the last example, which makes two technologies here, here it's a snippet from a Spring Boot application written in Kotlin. And here you can see with Spring Boot, we provide some nice features here, something that's called the Keycloak REST template customizer, it's just like a regular Spring REST template, but it takes care for you of putting the token, the access token in the header for you. So you don't have to take care of anything, here your customizer, your REST template, and here if you do a get to another service, it will just put the header for you, okay? So, enough talking, let's move to some code and some demo. I have a really simple web app here, really simple, it's just some HTML and some vanilla JavaScript, and all I have done here is adding the, as you can see here, the Keycloak JavaScript library. And on top of my page in the navigation bar, I will have here a button called login, and I just call the login method, okay? And that is the application running here, really simple app. And when I will click on logging, I will be redirected to my Keycloak server to enter my credentials. So let me click here on login, and here I'm on my Keycloak server. I'm not on my web app anymore. Here I can log in with a user I've previously created, Sebi, and I gave it password Sebi, and I just log in. And now I'm redirected back to my application, okay? And if I go to token here, I can see that I have my free token that I spoke before about. I got my ID token, and I get my access token. You can see it here in JSON format, and I got my refresh token. When I will make a request, I will use my access token, but I won't use it in this format. That is not really convenient to pass as a header, as you understand. So what I will do, I will convert it to a base 64 format like this one, and this is what I will put as value in any request I do, okay? Now, that is on how to obtain a token. Let's try now to make a service. So here I have a button, and if we go back to my code here, and we go to app.js here, we have the simple call, and this is just like the code snippet I showed you before, and I'm trying to call here localhost 8081 products. That service doesn't exist yet. We're going to write it from scratch. And you see here, I just passed the token. So if I go back to my app, and I try to make the service call, nothing happens. We can even see that on the inspector here. If I do my service call again in the network and I do a service, it fails because the service is not present. So let's create from scratch our first service, okay? And for that, we will create a Quarkus app. For those that don't know Quarkus, Quarkus is the latest coolest Java stack to create application, Java application for the cloud, really low memory footprint, really fast and amazing developer experience. And that's why I can do it live from here. So let's go to a terminal here, and let's create a new Quarkus app. Okay, so here I create a Quarkus app using a Maven archetype, so Maven Quarkus plugin, and I call the create goal. And here I say create a new app, and here I will have some questions. So let me see, how, let me set the package. So it will be org.savvy. I will call it the product, okay? Oh, the product service, sorry, product service. Version one is okay. Yes, I want the rest resource, and it will be called org.savvy.productresource, okay, and the pass will be products, okay? And now I have created an app, an empty app that just contain one rest resource, and I can just open this in my IntelliJ, okay? So let's go to IntelliJ, and let's open this application that I just created. So here I go to destination, and I see here my product service. Okay, let's open that in a new window. Okay, here we go, and it will just load my project here. It should take a little, okay, here we go. And if I go to my main source Java, I take a look here, oh, I'm clicking too fast, org.savvy.productresource. Let me make this a bit simple, a rest app. I could run that, it could work. But what we want here is to add some key cloak and make a secure rest endpoint. So the first thing that I will do is add some extensions. Extensions in Carcass are like plugins to add new features to your app. And I need two extensions here for my app. The first one, I need something called rest easy json b. Json b, because I will manipulate some json, I enable auto-import, okay? And the second one that I need, of course, is key cloak. Oh, let me add here Carcass slash key cloak. Okay, and that is all I need. And now I want to create a secured resource here on the path products. And let's make a method called get products. Here we go. And it will just return for me a list of products. So let's do it. Let's return something called arrays as list. And here I pass my product. And let's pass another product, like other product. Okay, here we go. And here I need to change this to return a list. A list of string. And I'm almost done. I need to specify it's a useful list. Okay, here we go. And now I want to secure that method. And that is pretty easy here. I will just say roll a load. And here I say that only authenticated users that have the role user and my user savvy that we, for which we obtain a token has the role user. So that will work, can access this method. Okay, and well, I'm already almost done. I just need to add some properties in a property file here from Krakus. And because it's a bit boring, I have a template for that. But let me go through it, pretty simple. Here I say where my keycloak service running, the name of my service, and only which will. Okay, that is all I've done. Remember, completely from scratch. Okay, let me just, you should not do that at home, delete the test because I changed the resource and by default my test will not pass, but okay. And now I can run my app. So let's go back to my console and to my terminal. And let me see. I'm just sorry, I'm stuck. I'm not used to use a Mac. So let me see here. Okay, let me close this one. And I just want to move to, oh yeah, here we go, sorry. And here all I need to do is maven package, package Krakus, let me call on Dev. And that will package my app and run it. And it's failing. Oh, I forgot to go in my, I was not in my project. So here I'm in my project. It will package that as a drawer and it will run it and then my service should be able to access it. Okay, so it's taking some time. On my computer it's faster. That's just a small MacBook Air for my daughter, which is not the fastest. But believe me with Krakus, your app should start in less than a second. Okay, here we go, it's running. So it started in three seconds. Yeah, that is a bit slow. We can just make sure here if we go to my service, localhost 8081 slash products, I should have an error, not authorized. Okay, so that means that my service is secured. But now my app here, I still have my token. I should be able to call my service. And this time it should return some results. And here I do my service call and of course it's not working because I have a demo effect. Like I'm not sure why. Oh yes, no, no, no, no. You know what? It was part of the demo. It doesn't work because I have course issues. I need to add a course filter to my app. And that is a great opportunity to show you that I can fix that in my Krakus app without even stopping the app. So let me go back to my Krakus app, which is here. And just while my app is running, I can just create a new class. Let me create a course filter class. Okay. And here again, I'm using a template because it's easier. Pretty simple course filter for those that knows course. And here I just save it. And now if I go back to my service call here that I call it, I should now be able to make a call. Let me see. Here you see my products, it is working. So, and if we take a look at the call here in the preview in the header, you can see that I pass here the authorization header. Okay, so that was the first step. Now I want my Krakus app to be able to call another service and it will be a Node.js service. A really simple service that just returned an additional product, okay? But let's first fix that in the Krakus app so that we can make a call to another service. Let's go back to my code. Here we go. And what we will do first thing is we need to add a REST client. And this REST client, it's called, here we go, and I paste it, sorry. We'll see, oh, oh, it's gone. I do control its command. I'm on a Mac, of course. So, it's Krakus, a small REST client, okay? And with that I will be able to, here I made typo and here we go. Small REST client. With that I can create a simple REST client to call other services. For that I need to create an interface. So, let's create a class called premium. Premium service, okay. Premium service, okay, here we go. It's an interface, here we go. Let me make it a bit bigger. I just need to annotate this as a REST client. And also, I need to register the client headers. I will explain you that later. That is to propagate my token. And I need to provide a pass. And the pass will be something like, let me see, it will be something like premium slash products. Okay, and here I need to import this, okay. And it will be just a simple returning a string, something called get premium. And it will be, oh, and it will just, oh, sorry, now it's an interface. I don't need to implement it. Sorry. And that is all I need to do, get premium, get string, okay, here we go. And now, in my product resource here, I can just inject my REST client. So, I'm going to name it as REST client. And it's my premium service, premium service. And here, I can just do string, premium. And I do my premium service. Get premium, okay, here I need a semicolon. And let me add the premium product here to my list. And here we go. And last thing I need to do is to add some properties again. Here, let me again use some template here. Here, I just specified where my REST client should consume the service that is on local host 3000. That is where my Node.js service will be running. And the other really nice thing here with Quarkus is that you have something called propagate headers. And here I said, when you receive a request with the header authorization, just propagate this header in your REST client. So, I don't have to take care of any access token to be present, it will be done for me, okay? And that is all I need to do, okay? So, let me just go back here to my app because I added a dependency, I just need to run it again. And while it's running, let's move just for a while to my Node.js service that we are going to consume. So, with Node.js, you have a key cloud module called key cloud connect. So, you just add it to your package JSON and you declare it here. And then it act as a middleware for Node.js Express. It's pretty easy to set up. Let me skip that because we are already a bit late, but what is nice here, when I define my Express route here, so on premium products, I just need to pass it as a middleware. So, here I say key cloud protect, the user should have the wall user. And here I send another product back, premium phone, okay? So, let me start this app. So, let's start in debug mode, should be fine, I think so. So, here my Node.js app is running and let's make sure it's running. So, if I go here to 3000 slash premium slash product, oh, it's good, okay, it's complaining because it doesn't have any token, which is perfectly fine. And it gets here and acts as deny. So, my Node.js service is now protected. And if I go back here to my app, now if I do my service call, I should have a third product coming from my Node.js service. And let's hope the demo gods are on my side. And if I call here my products, well, I'm not lucky because it's complaining because what is happening? Oh, you see, I maybe missed something. Then, that's public, could not find a method for abstract get premium. Okay, so let me just go back to my code. I maybe had done something wrong here. Let me check premium service, get premium, premium service. Res client get premium. I don't see anything. I just take a look on my backup, which is on my other computer because I really want to show you that premium service. Oh, yes. I did the wrong annotation here is register res client and not west client. Sorry. Okay, here we go. That should be the better. And again, I don't think I have to reload. And if I go back here, it's still complaining. So, maybe I need to reload and let me just break this and run it again to be fast. Here we go. Let me just make sure I haven't missed anything. Premium products, okay. Let me see my properties are through it. That looks okay. Or SEBI looks fine. Should be okay. Okay. And let me do your service call. And it's not working. And I don't know why that is not funny because it worked working just before. Could not find a method for abstract get premium. It's so, oh, sorry, sorry. I know, I know. I need to clean here. Clean because it was still packaging without recompiling. Yeah. I wanted to be too fast. I'm sorry for that. And let's make a last attempt. And otherwise we will move, well, we are close to the end already. But, okay. So, here we go. And just let me sure, let me log in, log out again. SEBI, SEBI, here I log in. And here I go to my service call. And I call my service. And it is not working. I'm so, so sorry. I under the stress. I probably missed something. Public. Oh, sorry, I know it. I'm typing way too fast. I, yes, public. You know, I'm a old string. Oh, get premiums. That should be good. I don't know what. Oh, yeah, yeah. Sorry, sorry. I'm really, really too fast. Let's just finish that because I really want to show you that. Get, I forgot some annotations. And I need to produce this. Here we go. Application text. Okay. And that should work maybe without a reload. I'm saying that several times already, but this time let's, because our thing is at the torque. Okay, here we go. We see I'm happy it's working. So here we got my two products from my Quarkus app. And this one comes from my Node.js app. Okay. Took some time because I was not typing good, but that's it. Let me see. I, do we have a hard stop or can I show a last thing? I don't know if someone from the staff can tell me that because there's a really last. Yeah, maybe you should. Sorry. Can I go on for two more minutes? Yeah, okay. I, let me just check here from staff. Can I go on for a while? Yeah, can anyone go ahead? Okay, let me just show you the last part. So because I want to go a step further. I want to also change my Node.js app, so it can make a call to a third app. And I told you it can call a PHP service. And for that I'm using something called HP Propagate and Request. HP Propagate will just make sure to propagate my headers as well. Okay, that's like what we did for the other app. So let me just do this really quickly, HP Propagate and here and just instantiate it with this. And here we go. I need to provide just an headers to propagate, okay? And here I pass just a small stuff like, well, what do you want to propagate? Is my authorization header. Okay, authorization header, that should be okay. And then if I go here back to my method, I was smart enough to command that out here. And here I call here my PHP service which is behind a proxy and that should be okay. So let me restart my app and let me start the proxy that is behind my PHP service. We don't have time to see exactly how it works, but now if I go back here, let me make sure my PHP service is there, secured. Yeah, that's great. I got a 401, that means it's secured. And now if I go service call, I should have, yeah, here we say. So let me zoom in. My products, other products and my Node.js service is calling the PHP service. And yeah, I forgot to change the string, but this last string here is coming from my PHP protected services. And that is really what I wanted to show you. I don't have time to show you the authorization part that will be a next destination session, I guess. But at least we saw three cloud native technologies, Quarkus, Node.js, and a Go proxy to protect any app, how you can put that in place to secure a whole set of microservices with key cloud. And let me go back and I'm now going to stop the screen share and go back to a video, so if the stuff. So yeah, that was really quick. And let's, I hope you enjoy it. I will, there are some resources of the demo which are already available. I will share that, I have a complete worship around that, that this take more time than this 30 minutes, but I will share it with you. And let's try to answer some questions. Epson, you going to help me for that? Hey, I see Bird, but it's Epson. Let me just drink some tea. So we have a lot of questions I see. So that is some comments. Have we selected some questions? Oh, Epson, have you selected some questions? Oh, apparently Epson is from mute, but I'm looking. Are the code shared on this session answered? Yes, I will share it. The example, yeah, all the example that I showed you will be shared. What can I see here? Can Keycloak run on OpenShift? Yes, of course. Here for demo purposes, I didn't run it on Keycloak, but I didn't run it on OpenShift, sorry, but yeah, we are working really well on OpenShift and with the next OpenShift, there's a really nice stuff coming around Keycloak and operators, which will make it so easy to deploy to upgrade your Keycloak server. So yes. Will there be a recording? Yes. Thus, free skill, yay. All right, hello, now I'm back. I had to refresh. Oh yeah, I'm back. Unfortunately, we ran out of time and we had a lot of questions in the session. First of all, thank you very much for the nice demo. We know that live coding is very hard. And what we can do is that we're going to take all of the questions and send to you. Maybe you can share it later on the YouTube video link so the audience can get kind of answers. And again, I would like to thank everybody that was watching. Thank you, Sabi, for this simply awesome presentation and see you on the next definition live.