 Hi, everyone. I'm Brian DeMers, and today I'm going to show you how to build and parse JWTs with a Java library named JJWT. JWTs are used for a variety of things nowadays, not all of them good. The typical usage, though, is you have to encode data that you want to then cryptographically verify on the other end. So, like microservices or some stateless operations, JWTs are commonly used for OAuth access tokens. Though if you're trying to validate an Okta access token, I'd recommend you use one of our helper libraries directly. The Java one uses JJWT under the covers. Now let's use IntelliJ to create an example project. Select for a new project. Standard Maven Java 1.8 Call it com.okta.developer And the artifact ID is JJWT. IntelliJ likes to drop my dashes, but I like to add them back in. Give it a unique project location. So my module name is JJWTExample. And we'll click Finish. Of course, IntelliJ warns me because the directory doesn't exist. I'll let it create that. I'm going to tell IntelliJ to import the project automatically with auto imports. Alright, so first up, I need to tell both Maven and IntelliJ that I'm going to compile at a source and target version of 1.8. So I have some common props here. So 1.8 is my source and target, and I'm using UTF-8 for the source encoder. So next up, I need to create some dependencies. So JJWT, typically you would import three dependencies. The first one is jjwt.ipi. The version is 10.7. Sorry, 0.10.7. If we're hard at work on the next release and soon after that would be 1.0 release. So the next dependency is JJWT.imple. Again, the same version. This time we need to change the scope to runtime because we don't want to compile against the runtime implementation, just the API which has the interfaces. And last up, we have a dependency. We need a JSON parser. So we're going to use the jwt.jaxon module, which uses JSON, but you can also use JSON and upcoming support for JSON as well. It's the same version, and I'm also going to use the scope of runtime. So that's all you need to do. Basically it's just this dependency that you're really concerned about, but if you actually want to run the project, you need two more. So let's go create a package. We will call it com.octa.developer to match our group ID. And create a simple main class app example. Alright, so let's create a main method called ecstatic void main string args. Alright, so far pretty standard Java main method. So jwt, you typically use a helper slash factored class named jwts. This provides a fluid interface to get you started. So jwts, we can use a builder, which will give you a jwt builder. From here, we can just start adding claims. So I'm going to set the subject to my name, Brian's Merge. I'm going to set the audience to whoever's watching this video. So video demo. And that's just a string. And next I'm going to set an expiration time. So let's use Java instant. Now instant.now. So we set the issue.time. So we can do date from instant, which is now. So that'll say the time this jwt was created. And then we want it to expire. So let's set expiration of date from right now. And then we want to add a little bit of time. So we're going to say this is valid for a minute. So let's do plus one minute. I also want to create a custom claim. So out of the box, jjwt supports all of the standard claims with nice setters for you. But of course you can use any claim you want in a jwt. So I'm going to say I'm going to add a claim of 1d20. And I'm going to give that value a random extents 1 through 20, right? So we're basically rolling a d20 here. So I've set some claims. I've set the expiration. Now all that's left to do is turn this jwt into a string. So I can call compact, which basically takes everything, compacts it into a single string. So this returns a string. So that's my jwt string. Nice fluence interface. And of course I need to do something with that. So let's just print it. So I can just print the jwt string. Now if I run this method, you will see that I have a jwt. However, this only has two parts. That's a header and a body. So it's missing a signature. Because I didn't tell jwt what it should use for the signature. Now in my case I'm going to use a shared key. But you can also use public key cryptography as well. So let's create some random bytes here. I'm going to go to like terminal. Of course it takes a second to open up here. I would use open SSL to create a random base64 encoded string. There it is. So I'll say my byte array is called secret is base64 encoded string. So we need to decode it before we turn it into our bytes. And then we'll decode it to string which is what I just generated randomly. Now we can go and tell jjwt to use this key to sign. So we have a nice helper methods to do all of this for you. So we can say keys.hmac, SHA key for these bytes. So I'll use this secret. All right, so now when I print it out again, I'll get the signature as well. Here we go. So here we have the header, body, and the signature. So if we take this jwt, go back to our browser, paste it into jsonwebtoken.io. It'll show me that I'm using the algorithm HS256. And here's all the data that is in the payload. And we apparently rolled a 13. All right, so there's the expiration and issued at time as well. And hopefully they're one minute apart. So now that we have our jwt string, you would have some other service somewhere, some other process that needs to decode this value. So let's do that. So we start the same way, jwts, parser, and we're going to parse the claims jwts. And we're just going to pass in the string. And this is going to return jwts with a set of claims. Call it result. Oops, what happened here? Whoops, that's fine. Sorry, typo. All right. So I can even print this. It's sort of pretty formatted for you. However, if I run this, you'll notice it will fail because I didn't tell the parser which secret key to use. All right, so sign and key must be used. So I can go back here in my parser and set the sign and key. And I can use the same method as above. So now when I run this, it should work. Right, so now we have a jwt string or parsing it. So the header HS256 again. And here's my body. So if you want to print out anything specific, so it works just the way is the creating the jwt. So you can do results. Get body.getSubjects, which would print my name or get audience, which would print video demo. But let's just print the dice roll. All right, so 1d20 result.getBody. And this is a custom claim. So just get and we would say get 1d20. Now if it's a custom claim and it's some other type of object, you can actually tell JJWT what the claim type is as well. So you could pass in class. In my case, it's just an integer and I'm just printing, but we can do this in integer. And that way the get method will return the proper type. So if I run this, we'll see what we rolled again. Six, not great. Okay, so this is cool, but typically you want to do some extra validation when you're parsing a jwt string. So built in support for the validation. That way if validation fails, the parser will not return the results. So I'm going to require an audience and I'm going to say it's a blog demo. This doesn't match jwt itself. That's why I run this. This will fail. Look at that. Expected the claim to be blog demo, but it was video demo. So let's fix that. Here we go. Cool. Oh, we rolled a 1. But anyway, the good side is everything parsed, we validated our audience. All right. So one last thing I wanted to talk about is expirations. So the expiration dates are handled automatically for you as well as the other date attributes like not valid before claim. So in my case, this claim is valid for one minute. So instead of adding a minute, let's do something a little superficial and we'll say the jwt expired a minute ago. So we just minus a minute. Now this will fail because I'm trying to parse a jwt that has already expired. Right. So the jwt expired. The clock skew is zero. So maybe you have some servers that the clock skew is a little off. So you want to tell your parser to allow some some small window of time for your clock synchronization. So we can do said allowed clock skew. And I'm going to say it is 61, 61 seconds. So that'll give us enough time to say our jwt is still valid. And this should parse just fine. Whoops. What did I do? So allow clock skew. Subtract one minute. Uh-oh. How about 62 seconds? Ah, I just missed that window. So 62 seconds was fine. So I've walked through creating a jwt and parsing jwt, adding some validation and showing you how to configure your clock skew. I hope you enjoyed this video. If you want to learn more about JJWT, check out the GitHub project. I'll add a link to the page in the description below. And remember to subscribe to our channel. We have videos coming out weekly. Thank you.