2020.03 Launch Webinar Part 2 – Secure your Apps and Services
2020.03 Launch Webinar Part 2 – Secure your Apps and Services
Today’s webinar is an overview of the new plugin that was released in Servoy2020.3, the JWT plugin. And as we usually do in these demos, in these webinars, we’re going to do a bunch of demos first and then we’ll jump into a bit of overview about what we saw, but we’d like to really show you what’s possible and then make the materials available for you to figure out more information and how to do stuff. So I’m going to give three demos today. They’re all very brief into the point. The first one is just an introduction into sort of what JWT is or JSON Web Tokens. We’ll generate and verify tokens. On the second demo, I’ll show an example of token-based auth for applications, so sort of auto-logging and users into your applications that they have a token. And the next example, I’ll show token-based authentication for services because that’s a common approach to securing web services. Remember, let’s do some overview. So let’s jump into it. What you can see on my screen right here is a quick demo application that I put together this morning and I’m going to walk you through generating a token and verifying a token. So first of all, JSON Web Token is exactly what it sounds like. It’s a JSON payload, like serialized JavaScript payload that’s encoded in a string token that you can send to a server. You basically receive from a server and then you can resend it later to assert that you are who you say you are and you have access to what you say you’ve been granted access to. And that really could be anything. So I’m going to make up a generic payload. We’ll do our hello world. And I’m going to generate the token. This is using the plugin. Now you can see over here I have a string. It has three parts that you’ll see separated by these little dots. So there’s the header. Excuse me, the payload and then the signature and I’ll get a bit more into those. And if I clear the payload over here, I’m going to verify it in the other direction. And this is if I were to later to decode or verify the token, I get my payload back. Another tool that you can use is you can take a token and I’m going to go over to JSON Web Tokens, IOGWTO and I’m going to paste my token in there and it’ll actually show you the decoded version. Now I don’t mean encrypted or decrypted. It’s actually just base 64 encoded. So this part is not encrypted and I think that’s important to note. It’s just base 64 encoded. It’s the bottom part, the third part in blue here, that is the signature that you generate the secret to sign the token. So this is what exchange back and forth and includes the signature that you generate when you make the token that you can then later verify it only you can verify. So you can see that the payload is the part in the middle, that’s the important part. So this is a nice website for more information and some tools around JWT technology. Another part of the SPAC is that you can set an expiration for your tokens and you should set an expiration for your token because tokens are sort of an implied grant to some resources and you want to make sure that those might expire someday so that you force the accessing party to re-authenticate. So I’m going to do that this token expires now in 10 seconds. I’m going to generate it and if I clear this and verify it, you’ll see the expiration date here and this is part of the JWT standard. These are I believe second sense the epochs. So that’s January 1, 1970 GMT. Now I believe 10 seconds have passed so I’m going to clear this and hit verify again and now you can see that the token is invalid. So in this case the server will no longer say that the token is verified. Let’s jump into the developer and see how this works quickly but before we do that I want to point out one thing. When you are signing your JWT token and verifying it you need to have some kind of secret key or client or server secret. So as part of the JWT plugin the first thing that you want to do is go to the server plugins page on your Servoy admin settings or into your Servoy.properties file and set this property the JWT secret password to the secret password you want to have. This is going to be required on any server that can generate and verify tokens if the password changes then the tokens will no longer verify the same. So that’s the important sort of cryptography part. So that’s sort of step one. Then you get inside a Servoy developer and I’m looking at the JavaScript code that’s behind the example form that I’m showing you and there’s really just a couple of methods here. The first one is the generate method. I have a variable here for the payload that’s the one that I typed in the hello world. The token is what gets generated and the expires in is when I put in the setup and those are bound to those fields. Then I call the generate method and what this does is if I specify the date what I do is make a JavaScript date so it’s nice and easy you can just do new date or take it from a data provider, call them variable etc. And I just set it expires in 10 seconds in that case. But then the magic happens here plugins.jwt.create. So that is the JWT plugin that now ships with Servoy if you have the latest version you will find it here plugins. And then as that nice colorful JWT icon there and you can see that there’s really just a few methods. So it is dead simple. So I create the token it returns a string. And then I do something with that token. I give it to my client. I put it in local storage. They use it in their third-party application. Whatever it might be. But later they’re going to send it back and ask me to verify it. And that’s where you do the inverse. So again I call that JWT plugin I call the verify method. And I pass in that string token and I should get back the payload that middle part of the token that has all the information about the claim. If that is null it just means that it’s invalid. Meaning that the token is not right or it’s expired. It doesn’t matter what it is. In fact you saw the little bit of maybe the error in my console here when I first switched to the IDE that actually throws a little bit to the logging at the warning level that it was a expired token. And you would have seen that in the trace log. In this case I just either printed out the payload or I said it to invalid. And that’s how I was able to show that. So that’s really just the gist of it. There’s two methods. Create, verify. And there’s also the setting on the app server or the Servoy properties for what your client secret is for signing the tokens. So what’s next? Let’s do a real world example. Suppose that I want to sign into an application and once I’m authenticated I leave and I come back in a different session and I want to automatically sign in again because I have stored a token. If you use any sort of cloud services you get this all the time. Maybe your mail provider, Gmail or something. You’re not asked to log in every time you fire up your browser and it automatically has you signed in. But every now and then you’re asked to re-authenticate. That’s because your token has expired. So let’s take a look at an example of that. What I’m going to do is come back to my example application and I’m going to log out. And I’m here at the login screen. I’m just going to log in again as admin admin. And now what I’m going to do is I’m going to close this and I’m going to relaunch the client. So this would be a new session, a new session. And you can see that it skips over the login and brings me right here. But you can see over here that it’s still the admin is logged in. So what I’m going to do is log out and walk you through that a bit. And I’m going to do that by opening up my inspector tools in Chrome here. And I’m looking at local storage and you can see that I have I’m printing out if there’s anything set in local storage. So when I log in, you’re going to see if I expand this here, that there’s a property set in local storage for my auth token and there’s the token that was generated. So when I closed this and I come back and I relaunch it skips over the login, then I bring this up, you can see drag this down that the token is still on local storage. And that’s how I was able to determine that that hey, this user is granted access and they can log in. So let’s take a look at the code. If I go to my example application and I look at the login screen on the first show, I’m checking if the user token exists. But before that, I logged in and I successfully logged in. So I set the token. So let’s look at that. So on login success, this is an override from a base form. This is actually a base form that ships with one of our extensions. We had a webinar all about it back in January during the 2019 12 release. So go check the archives for that if you like the built-in security functionality that you see. But for this example, I just override the on login success. This is called after login and I call set user token, which I made in my example scope up here, example JWT. And let me load this up for you so you can see it better. Sorry, set user token. So this happens after login. And what I’m doing is saying, I’m going to give them a token. It’s good for 24 hours. I encode in the payload the tenant name and the user name. And down here, I just call that create again. And I just sort of encode that payload and sign it. And this I use one of the extensions web storage local storage. And I I just made it a little constant here for the for the key name that calmed out, serve way example off token. And so I just push that token into local storage. So then the next time I’m coming in in the on show event. And if it’s the first show, I call check user token. And this is where I go and I read that that key back from local storage. If it exists, I extract the payload. Remember, that’s the verify method. And I didn’t even check it here. I probably should say if payload because otherwise it’s an invalid token. But I extract the user from the payload and I log the user in through the security API. Finally, there is a a method I wrote called clear user token. And I would call this on logout. And I just remove it from local storage. So all of the local storage stuff is another extension. That’s another topic. But this is an example of what you might do with a token. You might push it to local storage and push it in cookie and let a user re authenticate for a certain amount of time. You could also provide a method to refresh a token. Same sort of thing. So it gives you you a bit more control over that auto login process. You could create a token, a temporary token for a lost password. But one thing that that’s really nice is they’ve tokens, they encode that payload, which makes the whole process stateless because the actual state is encoded in the token, you don’t have to go and save some transaction on a database and then look it up later and manage all that is all managed inside the token. And that’s the power and the purpose of KWP. So that’s the second example. The third example I want to look at would be a web service. And suppose that I want to authenticate into a web service. And then once I’m authenticated every request that I send is going to be able to just pass in a token and sort of skip over the authentication. So the same sort of process but for a service, not an application. I’m going to go over to Postman, which is a a nice tool for testing web services. And I’m going to show you two who request. The first request is going to an endpoint and I have a web service set up right there in my little sample application. And that’s the off end point. And what I’m going to do is use HTTP basic authentication. I’m going to send in my username and password. I’m going to verify the user login. And then the off end point is going to return the token. So I’m going to go ahead and send that. And you can see that I get back a payload with the token encoded in it. So then what I want to do is build another request. I’m going to copy this token. And I build another request, but I have one prepared here. Suppose I want to now I want to access my orders through my web service. So you can see the endpoint here has changed to orders. And this time I use the authorization scheme bearer token. So this is a standard best practice when you’re protecting web services with token based authentication. You use a bearer token that puts it in the header. So it’s not in the URL. It’s more secure and more standard. And I’m going to paste in my token. And I’m going to send that along. And you can see that it returned to 200 OK. And the example payload was just a hello world payload. If I were to mess up that token suppose with a few characters at the end. And I try to send it. I’m getting back a 404 not found. So it’s protected by the token. So let’s take a look at the code to how that was implemented. I’m going to go back or go down to a module that I created. I just stuck in here called example service. And it just has a couple of scopes in there. So the first thing I did was I hit the authentication endpoint. So that was this off B1. And in there, I did an HTTP get so that translates to Ws read. By the way, there’s a whole webinar about publishing web services that was done maybe a year ago. If you go to our archives, you can see the recording of that which explains kind of how to set up web services. I’m going to kind of skip over all that. Just go right to the code where the tokens are used. So the Ws read is is protected because there’s Ws authenticate in front of it. And that takes the username and password. So this is for HTTP based authentication. In this case, I didn’t actually verify my password. I just assumed the user is verified, maybe through SUI security module or my active directory, whatever it might be. But I verified the user. And then I generate a payload that just encodes the username in this case. And I say it’s valid for one day. And I call again, I call that JWT create token. And I return it. Now, this is a subtle caveat of the way the rest plugin works in Servoy. The authenticate handler here sort of got in front of the Ws read, which is the HTTP get handler because it’s there. It routes it through that first and checks the HTTP basic authentication. Then whatever you return out of that handler, gets forwarded on to the method that was called in the final argument. So I grabbed the the last argument that was passed in here. And that should be the token that was returned out of in this case, I’m not doing anything. I’m just going to return the token back to the calling agent. So that was the postman client. And that’s what you saw down down in the postman payload. So that was just to get the token. Then I saw me copy pasted and put it in the bearer token. I want to show how that was done. So I hit the orders endpoint. And the Ws read method. And what I want to do first is check the token. So I wrote a little utilscope here and I wrote a method called check token. So this goes over to a different scope. And because I put it here because this could be reused by, you know, all of the endpoints you have in your service. And it calls check token. And the first thing I do is I use the the rest plugin and I get the headers. Again, this is a bit off topic, but there’s a webinar about this. if you want to check it out, the archives. And I get, I get the headers for authorization. I assume there’s only one. So I grew up the first one. And then I look for a bearer token. I do a bit of parsing here and parse out the token from the auth header. And once I have the token, I return it back to the caller. And then here I again call that verify token, which verifies the signature in the token that it was generated here on the server with my secret password. And if it is, then we move on and I return the payload if not, I’m throwing a 401 or 404. So that’s it. That’s how I am going to sort of protect all of my services by putting this, this check token in front of everything and call that first and make sure that it’s in the header. If it’s not in the header, I should always just say not authorized. And that’s kind of the standard practice way of doing it. So those are the three examples that that I have to show for you. I’ll go back to the presentation and just sort of summarize what we saw and then talk a little bit more about JWT. And we’ll take some questions. So what do we just see? The first thing I did is I went to the Servoyadmin server plugins page or I could have gone into my servo. We got properties file and I set the value for that secret password that’s going to be used to sign all the tokens. You got to do this. Otherwise, the methods in the plugin will just throw an error that says you haven’t done it. Also, if the password is not the same from one server to the next, it’s so suppose you generate the tokens on an auth server, but then you use them somewhere else. If you don’t have that set the same, then the tokens aren’t going to verify because they’ll have a a different signature. Step two, as you just generate the tokens as needed. So you just call that create method and you specify the payload and that can be anything of your choice, but this sort of represents what’s in the claim. The users logged in or it could be I have access to ABC through some service, something like that, anything you want, but it’s an object that you construct and it should be serializable easily. The expiration date is optional, but it’s always recommended that when you make tokens that they expire. Otherwise, that’s a bit of a security flaw. So recommend that you put in an expiration and like a default expiration into all your tokens. If you don’t specify it, then they will always verify they don’t expire. The token that’s returned is just that string. Again, that basically for encoded in three separate parts. And then later, the client application or the user is going to submit that token again and you get to verify it. So step three is to verify tokens and it’s again, verify method. You pass in that string object and you get back that payload. So then you can just you can read the payload if you need to to figure out what’s going on. The after I did the little walkthrough of how it works, the first demo I did was how to do the auto login or to do token based authentication. And what I did is I generated the token after the user successfully authenticated. And then I put it in local web storage or you could put it in a cookie or something. And then later when I’m coming in from a totally different session, I read the token and verify that the user still has access. When I click the log out button, I cleared it from local web storage. So I just removed it. So in that case, I’m using the web storage extension that’s available through the package manager. It makes it really easy to push stuff and store it into the browser local storage. The second example I showed how to do token based authentication for web services, it’s kind of the same flow except it’s not a user using an application. But instead, it’s a HTTP client. And the first thing they do is they authenticate username and password and then they get a token and then they keep the token in the client application and submit it with subsequent requests. And in this case, I used our REST plugin to verify, so to extract it from that header to then verify the token using the J-DAPT plugin. Just a bit of overview about the tokens. Again, Jason Web Token is an internet standard and its primary purpose is to represent or assert a claim between two parties to say party A is being granted access to something of party B. And that’s all it is. And it’s a persistent way to do that. Now, the use cases of that are, they could be anything, but most typically, it’s that a user has logged into some server or some platform and that they are granted that log in. The second one is more that a third party client application has been granted access to some resources. So you see this in OAuth, for example, that I want to take my application and I want to assert that it has access to my LinkedIn profile or something, right? So then that’s kind of encoded in the token. Some of the reasons that JWT is used is that the token itself is pretty compact and it’s URL safe, so it’s ideal for SSO implementations. But the primary reason is that it’s stateless. So anyone could build a sort of token-based authentication system pretty easy, if you imagine that you generate some crypto key and you store the crypto key server side in some credential store some database. And then when users come with their their key, you verify it against it and maybe you have some extra information stored like what the claim is and what the expiration is. So that’s one way to do it, but that introduces the overhead of having to not only build that, but also maintain it and make sure that it’s working. A nicer way to do is to make sure that everything is just encoded in the in the statefulness of the token itself. And that makes the rest of the orchestration around that state list. There are criticisms that it’s a security flaw, JWT, that the payload itself is in the token. It’s only base 64 in code. It’s not like it’s encrypted or something. But you should just know that when you use it. It’s not like you put sensitive stuff in the token. You just put the claim in the token and that’s all you use it for. Otherwise, you’d have to make the token stateless and make the application stateful. So that kind of undoes the benefits of JWT. So that’s really the main benefit. So we saw that in the token itself, there’s a header which has the algorithm info, the payload, which is the claim part, the one that’s custom for your application or your use case and then the signature and that’s generated by the plugin itself using the password that you put in the server. So that’s the part that makes it verifiable. So that’s pretty much it. I’m going to, oh, I forgot to say, what’s next? What are we used this plugin for? I think that it makes sense that we provide some bridge between this plugin and the SFI security module so we can start to do maybe have some token-based authentication built into the security module, also maybe some lost password workflow that involves the token, etc. Also, maybe some example templates of how to do web services like I showed you using token-based authentication kind of built into some starter templates or something like that. So there’s some opportunity for us to provide even more on top of this plugin to the community so we’re looking into that. I’m going to leave out these useful links. Well, I take some questions. You can find documentation on our wiki. I made the demo solution of what I showed you available and just threw it up on a drive folder. So there’s the URL for that. I’ll repost this on all the channels, the form and stuff as well. And also, if you want to read about JWT and use that little tool to encode and decode tokens, you can go to the JWT homepage. Broker, do we have any questions? No, I think your demos are critical clear, Sean, because I don’t see any questions coming in. Okay. Maybe later on there are, but there’s a lot of documentation around this as well. So if there are no other questions, I would say thank you, Sean. Stay safe, all thanks for watching and hope to see you on Friday, same time. Yep, Friday will do the new Google Maps update the Google Maps component. So more demos and fun stuff. Yeah, something to look forward to. Okay, thanks everyone. All right, thanks, Ciao. you