Token Authentication for Java Applications

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
thanks Arthur thanks for having me guys so as sasha said my name is les hommes CTO co-founder storm paths why am i up here talking to you guys why should you listen to me well first of all you shouldn't you should go out do your own research the world of security is very interesting and there's lots of opinions but you want to be careful about the information you get so always do your your checks and your resource you know verification but I'm going to do my best to not steer you guys wrong as a testament to that I'm the code are the project founder and and project lead on apache shiro which is the security framework for the java virtual machine founded and fostered by the Apache Software Foundation I'm also on the j ee application security group which is a new jsr spec that's being formulated right now that will be available in GAE e8 and it really takes a lot of ideas from Shiro and spring security and codifies them into a framework that'll be part of the JVM moving forward which is pretty cool storm path who are we we are fundamentally an authentication and user management API were built for developers our primary customers are those that have applications they are building and deploying to the public Internet so all of the security breaches and the frustrations that companies like Sony and and all these other companies might have had we solve those problems password reset email verification integration with the secure identity stores we automate all that so you don't have to build any of the stuff in your apps anymore we are a security team at our heart so we do a lot of stuff with cryptography secure data stores you can do SSO across your applications but you can basically think of us as a specialized dressed JSON API micro service if you will for Identity Management so what are we going to talk about today there's kind of a decent amount of material and then the slide doesn't really indicate it as such but I'm going to kind of break this presentation down into maybe two or three sections the first half of the part patient is really about the problems that you kind of come up across in building secure web applications and also the techniques that we've used to date you know how cookies are used some of the problems around cross-site scripting attacks cross-site request forgery attacks and how to mitigate those or at least how to do that well with what we know today session IDs are often as back-end Java people we talk that's usually the primary go-to mechanism that we have for storing authentication States so we'll talk about sessions and session IDs and some challenges with that and then we'll talk about a new approach that has been pretty prevalent over the last 18 months or so it's quickly becoming sort of a de facto standard for identity assertions and authentication for modern web apps especially around single page applications or spas and mobile apps so we'll talk about what token authentication is how it solves those problems and also how to do some of these things and a best practices kind of way and then finally I'll finish out the night with a demo that actually shows these these principles being executed within a real application and I'll do that showing an oauth2 example so let's get into it security concerns for modern web apps some of the issues that you have to worry about when trying to solve or deal with security problems is that a lot of apps today are single page apps and mobile apps and these are what are called untrusted clients and they're untrusted because they run in a runtime environment that you as a server or application developer don't have control over my JavaScript applications can be accessed via the developer console you can change data or state client-side apps on Android and iOS can be decompiled so you can't embed things in there like API key secret values or user passwords that's never a safe thing to do so these are this that's why they call these things untrusted clients now when you want to support these things and browser-based apps you want to prevent malicious code from executing so we'll talk about some examples of what that is and how it works you want to make sure that your user credentials that you accept from your users like if they enter in a username and password on your web app and they hit enter you want to make sure those credentials stay secure you want to keep your user secure you want to secure your endpoints we'll talk about how to do that a little bit and then one of the things that's kind of interesting is for single page apps or any app for that matter you want to expose access control rules to that client or that code base to let the client know what the user is allowed to do you know can they add a user can they delete a user can they see this image can they not see this image you want to be able to do that in a convenient way so when we talk about malicious code what do I mean here in the in the context of this presentation we're going to talk about the the two kind of major concerns cross-site scripting attacks in xsrf attacks these things are real they're a big deal they happen a lot on the web on a daily basis we're not going to jump too deep into some of the definitions of what these things are I highly recommend that you guys go to the O s website and you kind of do some reading they will explain everything in detail but an XSS attack at a very high level is a malicious user or attacker can enter in their own JavaScript code into your JavaScript based application by using form fields as typically how this is done so they might you guys are familiar with sequel injection you know you want to escape your values or parameterize them before they go to the database the same is true of Web Apps if you have user enter data in a form field you want to encode it first before you interpret it to make sure that you don't just run it blindly so that they can inject code so as an example there's a little demo that I'm going to see if I can can execute for you guys this is a little demo that you can run let's see if I can get out a get out of here in a sandbox environment here we go so this is a little sandbox environment this is safe to run if you guys want to test this out it's not going to hurt anything on your on your browser but the next this this is an actual demo of what an XSS attack looks like in real life so let's say I go to a search engine or any form field for that matter and I type in you know hi and I hit Search it's going to run the code or it's going to run the search and the server in this case it says up no results found you know try again but if I was a malicious attacker I might do something like this where I can enter in a script a JavaScript snippet in this case I'm just doing an alert and if I hit the formfield submission see the JavaScript pop up it actually ran the code that I entered in the form field right that's a really bad thing from a security perspective because this could have injected code into the Dom and that code can then do whatever it wants to it can access your Dom structure can make HTTP requests without you knowing about it this is not a good thing so this is what an actual XSS attack looks like in real life and there are sophisticated script tools that allow you to kind of automate this across various websites but we don't want this to happen so how do you deal with that how do you how do you protect your web application from these kinds of attacks so there are ways to protect yourself basically good yes can you wait to the end of the presentation is it ok wait read everything you see on the sauce page right these guys are going to tell you a lot of how these things occur how to protect yourselves against them and best of all they have a nice little cheat sheet that you can see via this URL that allows you to figure out the best ways of protecting yourself in applications and these this is a language agnostic or at least it focuses on JavaScript solution set to help you protect your apps this basically boils down to escaping content so when a user enters in data in the form field you want to escape content make sure that you use an escaping library that does this for you don't don't don't try to create the parser yourself HTML has a lot of weird ancillary rules and conditionals and use cases use a well-known trusted parser for this to escape the content for you all wasp has one out of the box that they that you can use download for free it's open source it's really really well done highly recommend using that you know we really don't recommend that you roll your own pretty risky to do so um so the takeaway is escape user input so what else can you do in addition to that certain spa frameworks like angular and I think ember to a certain degree do a lot of this work for you right you can prevent Dom manipulation by escaping user input and they have sometimes automatic you know value readers that can do this stuff for you that said you shouldn't trust it 100 percent read up on it see how it works and and make sure that it's doing exactly what you need but you know do your due diligence in this in this case we also want to secure user credentials traditionally we've done this by using sessions and session IDs so the idea is that the user enters in a username and password they hit submit that data goes to your server you resolve that in a yes or no answer however you you're doing that and then a lot of times you'll take the the result the authentication result and you'll store it in an HTTP session that's the pretty common thing that most of us do is Java developers things like Tomcat and JE frameworks they do the stuff automatically it's not really you know have to think about it that much it just kind of happens automatically but the thing to keep in mind here is that when Tomcat does this it's setting it almost always setting the cookie sometimes URL rewriting that's not as prevalent and this is okay as long as cookies are being set correctly and you're setting the cookies in the right manner and you're utilizing them effectively authentication tokens can be better and of course that's the whole point of this presentation but we'll see we'll see how in a little bit so cookies what do we need to know about cookies in order to keep these things secure so this is the common flow that we're used to as Java back-end developers somebody's going to post a form to a login and then the result is at 200 ok or some other success status code and a cookies going to be set in this diagram it's a session equals some random string but in the Java world this is almost always a J session ID value and so that cookie is set and then the browser on future requests will send that cookie back to the server via the cookie header so if you set the cookie under the domain that the user accesses then the browser will automatically send that back to the server and it will know based on the session ID who that user is and this is okay traditionally you know if you want to talk about API endpoints instead of just browsers traditionally you use such an ID cookies to handle that as well so you go to the session ID you get the session ID you look up the HTTP session and from there you can get your account identity and you know who the user is frameworks like Shiro and spring automate a lot of this stuff for you especially with how to resolve accounts and how do you persist that state after a login attempt they automate a lot of that stuff so definitely recommend using these frameworks if you're not but session IDs don't really solve this particular issue of exposing access control rules to the client all right session ID you can use it to go find information out and go look up data in your database and send it back to the client and a lot of times you'll see web applications they have a /me URI or slash profile or something like that or slash access controller you know whatever it is at some endpoint based on the current user will give you back a list of what that user is allowed to do sometimes that's being done that way and then the client side can read that list and then turn on or off certain features in the user interface this still requires session state but again we think access tokens are better and we'll show you how so let's dig into some cookie stuff a little bit more from a security perspective cookies are okay actually if you use them correctly and if you you you would you understand some certain conditions that need to be met it's important to know that cookies can be easily compromised by man-in-the-middle attacks and so if you utilize a website and you log in over HTTP you know TLS and then you downgrade it to a non secure connection that same session ID is now snoopeh bulb I anyone sniffing network traffic traffic whether you're the airport or coffee shop anyone can take that ID value then start using it to pretend that there you session IDs can be thought of as a bearer token of sorts will cover bearer tokens in a little bit but they can be intercepted by men of the middle attacks and then used to assume the identity associated with that session ID cookie so oh and also cross-site request forgery attacks are very real issues when using cookies for user identity assertions and we'll dig into both of these so man-in-the-middle attack I just kind of hinted at it you know it's someone listening on the wire between the client and the server and they'll be able to see a cookie value and take that value and then maybe use it themselves by setting the cookie header to initiate attacks or assume the identity of someone they're not allowed to so it's really important to use HTTPS Everywhere like I had mentioned once you log into a website it's never okay or once you log in over HTTPS it is never okay to downgrade to an on htps scenario if you're using cookies to represent user identity this is a really bad thing it happens all the time never ever downgrade your security connection until the user logs out but it's important that you use TLS everywhere on internal networks too so just because it's secure going into your infrastructure doesn't mean it's going to stay that way you know if you have unencrypted connections across various back-end services those are potentially open up open to attack vectors and even if nobody in your team or your product you know is doing anything malicious sometimes those values can be logged they can be saved to files those files are inherently putting backup storage that storage could be compromised if it's not as secure as your production system so interesting tidbit I think something like 75 or 80% of all password attacks are based on my sequel dump files that are safe to backup storage right so you might think your my sequel online database is super secure and it may and it might be but your backup may not be and that's actually the largest attack vector for password cracking is my sequel dumps so be aware of about backup strategies you know these things are set as headers so if you log headers specifically you know cooking headers those could end up in a log file so be aware that so that's made in the middle I should also note that a TLS or HTTPS is not a panacea it does not solve all scenarios a lot of people think if I just have TLS on my website I'm good to go that is not true if you're in a coffee shop and you connect to an untrusted Wi-Fi access point that access point can acts can serve as a certificate authority and anytime you do a website request they can just automatically give you a certificate and just say yes this is the valid certificate of the site you're trying to access and you think you have a direct connection to your your final destination that's exploitable right so you'll have a TLS connection to the to the Wi-Fi access point and they'll take your data see it and re-encrypt it and send it out the wire to the real online the real destination there acting as a man-in-the-middle attack er so TLS is not a guaranteed solution it's pretty good most of the time but it's not perfect so just just be careful about that and you could if you want to talk about after the presentation strategies around that let me know but I'm not going to cover end-to-end security in this particular talk cross-site request forgery what do I mean by that so CSRF attack occurs when a malicious website or email or basically any any media mechanism that performs an on it unwanted action on behalf of the user without the user knowing about it so that's really a big mouthful to illustrate the following let's assume that I am a bad guy and you've logged into a legitimate web site you're an end-user you've logged into a legitimate web site legitimate user name password validation everything's good maybe this is your bank for example and everything's fine a cookie is set because you've created a session so now that cookie is in your browser if you then go visit another website a malicious website or an email and you don't know or you don't know the origin of that email and you click a link on the email what happens in this case is that the user will click on this link and it will be executed and sent to the server identified your website or the bank's website in this particular example and if the bank had no additional protection around this URL it could actually transfer that money to to a certain account somewhere granted this is a contrived example right banks don't do this kind of stuff but it shows you how these things can actually occur in the wild and the reason why this is okay or right why these attacks exist and they're successful is that the attacker can't see the cookie right the cookie perd browser domain policies is only sent to the server that set the cookie so the attacker can't see it but because that request is going to the same server that set the cookie the browser says I'm just going to give you the cookie and if your server just trusts it this is up I got a good session ID the the session has a user that I know about I'm just going to trust the request that's a problem because you've you've implicitly authenticated that request based on the session alone with no additional information this is a real problem this happens a lot there are similar attack vectors around images so a lot of times you guys use Gmail and you see that Gmail sends an email but it won't show you images in it it's because that image might be associated with an attacker that's doing trying to doing something suspicious and just showing the image will send a request to the server so they'll disable that by default so that you only need to show images from trusted websites for example to avoid some of these types of attacks so this is the attack vector how do we protect ourselves against it and there's three common solutions around this one is is called the synchronizer token approach there's another one called double submit cookie and then finally you can do origin header checks and we'll cover each one of these now so the synchronizer token approach works like this let's say that I am a travel agency and my user tries to get a list of flights and they get back a list and then they want to click ok by you know I'm going to a trip around the world is going to be awesome and the user thinks that this is or believes that this is your site and everything's okay and when they hit by it's going to send a post to a particular URI now if you look inside of the forum you'll notice that there's this hidden form field called CSRF token and this post will include that value into the request that goes into the server and the idea here is that the token value itself is unique and it's specific to the service that's rendering the webpage so it's a dynamically generated web page and only that server knows about that value a lot of people will store these CSRF tokens in the HTTP session and then it's okay as long as that value doesn't leave the the web server so as long as the client never sees this value beyond or rather if it's not stored anywhere outside of the server then you're okay and this will work so that on the submit the server will check yes this this token I know about it I generated it it can use things like digital signatures to make sure that it's untampered and hasn't changed but the point is that the server can verify that this token is present on the post now an attacker wanting to do a CSRF attack will try to do the same thing maybe they'll create a little you know form that says go ahead and and by you know trip around the world and send some money um when they click that button this is going to fail because they don't know what that random value is inside of the HTTP session right whenever they render their their fake-looking page for a phishing attack they don't have that token value so when they hit when the user clicks buy it will send a post to the correct web server your your web server in this case but it won't have the the CSRF token value because it can't generate a random value that matches something that is known to your application so this is called a synchronizer token you can use the same value in an HTP session and just use that same exact value over and over again I'm a little more paranoid when I do this for my web apps and the frameworks I build these are nonces basically numbers used once and so as soon as they're consumed they're immediately gone and then the very next time the page is rendered a brand new token exists so that prevents replay attacks which is always a nice thing because it's never used more than once there are some considerations around this approach it requires coordination from your rendering layer so if you're a server that generates HTML it's not a big deal because the server and the client here are effectively in the same process it does require you to store tokens in data stores or caches so whether it's a no sequel store or distributed cache you still have to store this state in somewhere and so at scale that can be a difficult challenge because you either have to put it in a clustered format and make sure that if nodes die the token still available the user doesn't see repercussions of died servers or dead servers but there are some engineering challenges with the stuff at scale one of the difficulties is that this is very difficult to do with single page applications because single page apps are pre-compiled they're static right a lot of times you'll use something like Bower to generate a compiled minified gzipped version of your app that is not participating in the randomly generated forms right those are all pre-built so you can't it's harder it's a lot harder to use the synchronizer token approach with spa's and another thing should be really kind of pointed out is that this only works with post requests because it's something that the server has to initiate before it's submitted back to the server so a pro tip in i guess along with that thought is that you should never ever ever manipulate server state with gets ever like it's always a security risk to enable that not only that but if you do that it kind of breaks the item potent nature of gets as mandated by the HTTP spec that's a whole nother talk so I won't go down that road so if you if for single page apps and pre-compiled mobile clients if that's not a great approach you know double submit cookies might be this a pro we'll submit two cookies usually one is a session ID cookie what we've been talking about the other one is typically a random value of some sort and they could both be sent as cookies to the server the issue with this particular angle or this particular solution is that the cookies are based on the browser same origin policy again only sent back to the browser that set the cookies and you kind of again you can't really rely on that because of the cross-site request forgery things that we've seen but you can set a cookie value as a custom header when it goes into the server and so I'll show you what that looks like this helps alleviate the cross-site request forgery issue so same thing we're going to send a post to a login page for an example and this time on the outbound response we're going to set two cookies one is our normal session cookie or J session ID if you want to look at it that way another one in this case is the CSRF ID token that is also set as a separate cookie but you might be thinking you know hey setting one cookie is still vulnerable to CSRF attacks why is setting two cookies any better and in the answer is because in this approach one of those two values specifically the CSRF ID token is set by your clients javascript to set a header on the outbound requests into the server right browsers won't do that automatically your JavaScript has to be able to manipulate the header and so yes the cookies will be sent back to the server no matter what but the server can reject the request if it doesn't see the custom header that it expects to see with the value that was set as the cookie and so if you guys remember with cross or same-origin policies and browsers HT ava's crypt based on HTML from a different domain is not allowed to set custom headers on a request unless those custom headers are approved by a cross origin request policy for the browser so this effectively eliminates that that attack vector because because malicious scripts can't set custom headers so that's really really nice the custom header could be whatever you want you can call it whatever you want it's not there's no RFC standard for this so it's whatever you guys feel is relevant the issue with this though is it's still vulnerable to cross-site scripting attacks so as I mentioned before if your app is susceptible to XSS attacks then somebody can inject malicious script into your browser and that can take can look at any value that comes back from the server so cookie values what have you or at least non secure cookie values and then takes that value and can send it off to their server if they wanted to and then they could take that and Forge your request back in your server because they they can set the header from you know a reverse proxy for example so this double submit cookie thing is valid you just have to be super careful to make sure that you encode user content so as long as you're doing that it's a good solution one of the ones I like the most is the origin header check it doesn't require additional cookies cookie values browsers by default will send the origin header well all browsers except for IE 8 but I don't know anybody who really tries to build for that anymore but anything better than IE 8 and any other major major modern browser will automatically send the origin header on an outbound request to the server and JavaScript clients are not allowed to set this header at all no matter where well I think you might be able to do it if it's in the same origin policy but I think that's on by default for every major browser for the for the origin that initiative that served the HTML it's always the value of the page initiating the request so again this can't be hacked via browser j/s you know compromised JavaScript runtime can't set the header maliciously and there is no special key that can be intercepted and used in a reverse proxy for example but reverse proxies you know malicious reverse proxies can set headers in any format they want so that is one potential caveat with this particular approach or actually with any of these approaches so I just want to be clear that the strategies that we're talking about are specifically around browser-based security models service can almost do anything that they want okay so we talked about some client-side stuff what about the server-side issues let's say that our session ID cookies are secure we're not susceptible to XSS attacks we're not susceptible to CSRF attacks and I still use a session ID cooking that's fine there's there's no real problems with that but they're all there are some problems it's not perfect so one of the issues with session IDs is that they're opaque they're just pointers there you can't look at a little session ID string and get any inherent value out of it you can't look at it and say oh this person's allowed to do X or they're not allowed to do Y you know it's just an opaque value that's just a pointer to some state somewhere one of the other issues with session IDs is as micro-service architectures are becoming more more popular and SOA architectures are becoming more prevalent each of these random services kind of might need to know about user identity and as a result they'll have to dereference that session ID you know hey given this ID what users associated with it and the more services that you have the more times that you have to do that so you might need to then build a dereferencing service just to figure out who's associated with that session ID and that causes its own set of problems and maybe a bottleneck in the architecture because they're opaque clients can't look at them and find value in them you know we I had mentioned this just a second ago but if I'm a JavaScript app I can't look at a session ID cookie and do anything with it doesn't help me as a JavaScript developer to do anything meaningful but the biggest reason why sessions are an issue especially at scale is that sessions equate to server state you know the more and more server state you have the more you have to synchronize it the more you have to distribute it in the cluster you have to make it fault-tolerant you know you don't want your user executing requests one minute and then the next minute you don't know who they are anymore it's a terrible user experience so if you use sessions and you store user identities in sessions or other relevant data in the session you still you have to deal with this this distributed state issue and at scale again this poses real engineering problems so guys like Facebook or Google or you know they try to avoid this at all costs you don't want it it's not a fun problem to deal with when you hit scale so you're hitting the server you're looking upstate on every request no fun so token authentication say answer to everything right maybe maybe not but token authentication is a sort of a modern approach based on everything we just talked about but this is sort of the second part of the presentation where we talked about all the things that we've been doing the last five to ten years and now how token authentication can maybe augment some of the strategies to get better results so what do I mean when I say token authentication authentication I think it's always important to clarify a lot of people have different meanings what it means when I say authentication I mean the process of verifying or proving the authenticity of a particular client or end-user so it's the process of proving that a user is who they say they are right that's that's what I mean by authentication in this case what's a token a token is really anything you want to be in most cases it's a self-contained singular kind of chunk of information that can be used maybe as a lookup mechanism as a pointer maybe there's some other intrinsic value in it but it I I mean a token in the broad sense of the word in this case but there's this really cool thing out if you guys haven't seen it yet called JSON web tokens JWT is very quickly becoming sort of the de facto standard for token based implementations across the web because it satisfies the needs of the two definitions that I gave a second ago but it doesn't a very easy convenient format that most people can understand it's easy to parse and construct but a JSON web token is a URL safe compact and self-contained string so it's you are all safe because of the coding that's part of the specification it's compact it's supposed to be very small the amount of data that's in and then base64 encoded it's not supposed to be a whole chunk of huge chunk of data and it's self-contained it's come pletely independent of anything else you can look at a JWT and and get meaning and value in it without having to hit another service potentially but the string is opaque and and it can be used as a token like any other string token previously one thing I'll note is that a big reason why starting become like a de facto standard is that while oh aw - and JWT are completely orthogonal specifications they have no dependencies on each other a lot of people who build oauth2 implementations end up using JWT s as the token mechanism in their JWT service or excuse me in their OAuth service so oo authors a protocol does use tokens but they don't specify in the OAuth spec or two spec what those tokens should look like and what format they should be in or anything so it's up to the aw - implementer to choose whatever they want and so most people these days are using J WTS as their token choice one of the cool things about J WTS is that their strings so you can store them in cookies and then that can give you a lot of power and flexibility but it should be pointed out that all those cookie rules still apply so you have to protect against CSRF attacks and XSS attacks but it's still a very powerful thing to have a JWT in a cookie and I'll talk a little bit maybe a little bit later about how that can be beneficial outside of OAuth because it is a string and it is a self-contained compact representation just like a session ID used to be or are they they are you can replace such an IDs entirely with J WTS because it's just a string and so is a session ID you can do the same exact thing with a JWT that you have with normal session IDs but they give you some more power more more more value and I'll break it down and explain how that's possible or why but this is what a JWT looks like in the wild it's just an ugly string there's nothing special about it but if you look closely there are two periods in this representation one of the top-line upper right and one on the second-to-last line on the bottom left and those two periods are delimiter x' and so you can break a JWT up into constituent parts why is it like that that's odd bear with me a second did it work yeah it worked so okay so there's a JWT split by the two periods as delimiters and when you look at these these these parts independently the the first part first chunk is called the header the second part is called the body otherwise known as the claims often and you'll see why they're called claims in a minute followed by a cryptographic signature and this is all base 64 encoded basically for URL encoded to be URL safe so if I took these chunks and they base64 decoded them as any JW client could you kind of get in all the good stuff inside so the header is its own little JSON object that tells you some information about what the body is like in this case we're indicating that it's a JWT by the type header and then the algorithm in this case says this is a JWT that has been digitally signed using the H max sha-256 algorithm so based on the header you know how to treat the body and whether or not to trust it based on a crypto signature in the body is filled with some data basically assertions is S stands for issuer I'll just jump into that the cryptographic signature is just a randomly generated by to rate it has no no intrinsic meaning but the issuer field is basically who created the token who is responsible for generating the token exp indicates when that token expires often you will want to have expiration times on your tokens you don't want necessarily users to stay logged in for forever there's a lot of good security reasons for that I should note that as a Java crew here expiration is indicated in value it's the number of seconds since epoch not the number of milliseconds so that kind of throws you off if you're trying to set these values yourself sub is the subject basically the entity for whom this this token is about or who it's representing basically the subject basically a user and this could be you know any kind of format any identifier user ID URL it's up to you guys and a lot of times you'll see people throw in this notion of scope into the into the JWT I should mention that scope itself is not a JWT reserved keyword it's not part of the specification but a lot of people add that to indicate what that subject is allowed to do so it's basically saying here's a list of permissions that this subject is permitted to do while using this particular application so awesome so we have this nice structured mechanism of representing data that's valuable to the application whereas the session ID itself didn't this is nice because it's implicitly trusted because it's cryptographically signed how many people here don't understand what digital signatures are how they work and it's okay if you don't because sometimes the stuff gets kind of hairy so okay so a cryptographic signature is a way of digitally verifying that data has not been tampered with right you should be able to compute a value think of sending some data into a black box with a verification key of some sort could be public could be private and the output of that value or the output of that black box is yes this matches the expected conditions or the or I don't understand this value it's been changed and it shouldn't have been changed so it's a way to verify the integrity of a data payload and almost all JWT s are cryptographically signed they don't have to be but and practice almost everyone uses sign JWT s using a server private key and that allows the server to validate came back in no one's changed it no one has manipulated the value the server can can trust that no one's try to inject their own data and changed values and stuff so digital signatures are used for data integrity they can also be used for authenticity but that's technically called a message authentication code it's a little different but JWT s are structured as we saw there's a there's the claims body you can have user name or user excuse me name value pairs so you can put whatever you need in them and as you saw with the scope attribute you can inform clients about what the user is allowed to do basically set up permissions and that's really nice because clients can inspect these values and turn on or off features in the user interface right they don't have to have a lot of these round-trip HTTP requests back to the server to say can they do this can they do that can they do this now I should be very clear that's convenient for the user interface but the server should always verify whether or not a user has permission to do something at the time that request is made right this is just a useful mechanism for clients but it's not authoritative the server should always have the authoritative answer on what's allowed or not it's just a convenience mechanism but the big thing here is that it's stateless because it's self-contained and has its own data you don't have to have server sessions at all all right the information that's relevant to your server can be encapsulated in the JWT so when that JWT is sent by a client or a browser into your server you can unpack the JWT verify the cryptographic signature to make sure no one's changed it and then you can just trust the data that's inside of it now I want to be super careful here JWT and signatures do not guarantee confidentiality so you don't want to store secure sensitive data in a JWT that's signed right anybody including clients can decrypt it not decrypt it but unpack it and see what those values are so you don't want to have things like passwords or anything like that stored in it you know Social Security numbers or things like that but it's okay to have things like user identifier z' and things that are generally seen is not not secure in and of themselves and if that's good enough for your app you can use it and completely get rid of sessions and you completely avoid server state for identity assertions which is awesome so these sound awesome and perfect and a silver bullet but they're not there's always kind of a catch to everything one of the interesting things about JSON web tokens in this manner and this is true of OAuth 2 how off - it does it is that just the fact that a client has the token and gives it to you means that there's an implicit trust from the client to the server there's no additional message authenticity guaranteed to be verified or confidentiality the fact that somebody has the token right it's a bearer right whoever has that information is considered the bearer and when they send it it's called a bearer token for that reason that's implicitly trusted there's no additional security guarantees beyond that a lot of people assume that just because it's TLS based they're good to go and for a lot of apps that is true like social apps like Facebook you know Facebook doesn't expose credit card numbers and stuff about your account so it's not a big deal if if some of that information is isn't perfectly locked down so part of the issue with this implicit trust is how long is it token good for you know maybe it expires in 30 minutes maybe it expires longer than that there's this notion especially an OAuth called refresh tokens on how you can exchange a refresh token and get back a new access token that's valid for another period of time for a given window and Refresh tokens unfortunately my kind of time to talk about them tonight but the issue with refresh tokens and access tokens there's always this kind of sliding window about how long the existing access token is valid for before it's no longer valid since you're not using server state to maintain that anymore the you know and you can use these two things to to change your windows depending on the security requirements for your application you know a bank might want to window five minutes whereas Facebook's is actually like 180 days so it really depends on your app there's no one-size solution for this stuff if you do use them in cookies I had mentioned you still have to secure them and as I mentioned a second ago JW T's by default are not encrypted so you can't store sensitive data in their JW t however it does have so when a JWT is signed it is called a JW s according to their specification JW t as a spec also supports encryption like aes-256 GCM kind of encryption that's called a JW e if you use encryption so those are secure and can contain sensitive information you can send it out of the server but most people don't use it for that because they only need to store user IDs and stuff like that and maybe lists of permissions so just be aware of those issues if you start using JW TS but weird Java group we want to know how you can do this in Java and I'm gonna use this opportunity to plug j JW T because I built it so it's awesome um but I think it's awesome but you know check it out there's a lot of other decent libraries out there too for the JVM but I'm going to show you some code examples using this this library to show you how easy it is to create JD bootys in Java this works on Android as well by the way so JJ JJ WT as a library works on both Android n and Java server side so in this case I'm going to create my JWT compact string write the one with the two periods in it and I'm going to set some fields I'm going to set an issuer field the subject I'm going to set an expiration time notice that takes in an maybe you can't tell it's not obvious it will take in a normal Java data object and do the millisecond second conversion for you you have to worry about that and then in this case I'm putting some non-standard JWT data in there in this case the scope because again that's not a reserved word and JWT and it just uses normal map semantics key values and then I'm going to sign it with H max sha-256 using an encryption key that I created and then I'm going to run the compact function so this is a nice fluent builder in faced to create these things in the JVM technically one one set of chaining calls so that's how you create a JWT and then like I said you can sort in the cookie or send it out you know and it's part of a response but how do you verify it once this goes out to the world how do you make sure that when it comes back it's still it's you can trust it and of course the library allows you to do assertions as well so you can set up a parser you know specify the signature key and you parse what they call like as I said acclaims jws so claims are is that specific type of body it's a jws because it has this that you're expecting it to have a signature so just calling this line of code will give you back the JWT and if it doesn't throw an exception you're good you know you know that the values safe and that you can trust it if it does throw an exception well there's all sorts of other exceptions so signature exception means clearly you shouldn't trust trust it because it didn't have a signature or the signature is invalid there's other things like expired exceptions or premature exceptions if you receive the token before it's supposed to be used all these kind of conditions are kind of built into the library but assuming no errors it's kind of like a one line code experience but highly recommend this one thing I am kind of happy to report there was a with various JWT libraries on the web maybe like a month and a half ago there was a snazzy little attack vector where people were using public public private RSA keys to generate digitally signed JW TS but they took the RSA public key and use it as an H mat key right in the server when it would get it some of these libraries just trusted that this public key was a valid H Mac signing key and they would use it and yes of course the signatures matched because they were using the key with an improper algorithm this happened with a lot of libraries on the net JJ WT did not suffer from that issue so we put a lot of effort and thought around the security around how to use this and it was nice that that none of our users got nabbed by that issue so that's how you do it in code but how does this translate to an HTTP service right we're talking about browsers or rest clients what what does this look like from an HTTP exchange perspective so I'm going to show one example in this example assumes that we have a single page JavaScript application like an angular app talking to your API server so it's your app talking to your API server what does this exchange look like and I'm going to use OAuth 2 as the example protocol here a lot of times I talk to people about OAuth 2 and you know the I start glazing back because oh there's all this complexity and all this other stuff and there's some truth to that Oh F 2 is kind of an uber spec but for this particular use case you're going to see how very simple a lot can be if you can ignore a lot of the stuff around it that causes frustration so this is an example of a request I want to obtain a token that represents an authenticated user and so in this scenario the user has entered in their username and password into a login form you know in my single page app and they hit the submit button and that username and password goes into my REST API server or just HTTP server and at this endpoint o auth token as long as it's a it's got an origin header set as long as the content type is URL form encoded content and it's got these three parameters that's all that's required for a username password based authentication in OAuth so they have this mandate you have to have a parameter called grant type to tell the OAuth implementation what type of authentication is occurring is is a username a password based or is an API key based and the username password scenario they call that grant type just the password grant type so as long as you have the grant past the password grant type and set a username and password pair that's all that's necessary for the OAuth implementation to generate a valid token and send it out and so the idea here is that the client side app is exchanging a user entered username and password and they're getting back a token in response and that's really valuable because that means that the users credentials the password is only exposed for a very small amount of time right they're not the client side app isn't keeping the password in memory and resubmitting on every HTTP request end of the rest api right that'd be kind of opening up attack vectors around cross-site scripting and other issues so it's nice if you can limit the window that the password is exposed and sent over the network tripping over the network so when I submit this token request assuming that the username and password match the expected credentials then the OAuth server can just return a JSON response notice the cache control and pragma headers are set you don't want this cached anywhere in HP caching servers or or proxy servers and then they could set this access token you know what the token type is when the expiration is this this is all codified by the oauth2 spec but the really important and easy thing to kind of recognize is that the uh Nexus underscore token I have unfortunately represented with an ellipsis but it's just a JWT in this case right it's just a string that conforms to the JWT spec that we had before so great so I've exchanged a username and password now I've gotten back a token what do I do with it how do i how do i leverage that token for future requests and the answer is that the client implementation can just use the the bearer header this is specified in the OAuth spec where they set the authorization header yeah authorization header and they choose an HTTP scheme called bearer the actual word bear followed by some white space followed by the JWT and that's all it's necessary for the server to get that JWT and then verify the digital signature make sure it hasn't been tampered with and then it can get all the data inside of it so it's really not much different than the cookie scenario because you're still getting a JWT it's still done via header and the authorization header can be set by JavaScript clients in the same origin policy but this is this is a very easy kind of flow you got the token you're just sending it back on the bearer header there's nothing crazy or special about this interestingly the same token end point can be used for API key authentication too so let's say I'm using an API key not a username password you know API key could be thought of it's kind of like a username and password but way more cryptographically secure and there's other properties around API keys that tend to be better for machine to machine communication but you can do the same thing in this case you see we're setting a grant type of client credential is not password and we're setting an API key ID and our excuse me a client ID and a client secret same endpoint the only thing that's different is the grant type and so that server implementation can change its logic based on the grant type it's very simple it's not this is not too complicated stuff there are a lot of complicated things about OAuth 2 but at least for the authentication flow it's not that difficult I will kind of mention that oh aw thisreally it was originally designed Oh F 2 was originally designed for what I call a three party workflow or they call this three-legged OAuth where you have an end user you have your own server your website you have something like Facebook right there's three parties involved in an identity verification flow and this we're not doing that at all it's just my spa talking to my app Roth and all of the other fringes around want the authorization endpoint who can do what is way overkill it's not necessary the only thing you really care about is exchanging the username and password for a token that I can use on subsequent requests so people kind of get confused about oh I'm only do an API key authentication or I don't understand this Oh auth stuff and how do I get it to work with Facebook and github and it's not really relevant you you can because it's a new respect you can pick and choose the things that you find relevant for your use case the difficulty is then wading through the spec and figuring out which which is relevant for your use case okay so that's an example of how this stuff works at an API level I'm gonna show you guys a quick little demo that I wrote if the computer cooperates so for some reason the CPU seems to be pegged and it's not it's not really going to you guys would be waiting for a while for each one of these things to occur so I guess I'll have to postpone the demo or maybe I can show you guys up here if you're curious about seeing what this stuff looks like all I was going to show you is I have a simple spring boot application that I wrote that all it does is the exact token authentication exchange so I'm using HTTP ie as a command line client to submit an OAuth request using grant type and username and password and then an OAuth token is submitted back and then I take that JWT and I just set it as the authorization header when I execute the next request and you'll see instead of hello world you'll see hello less right because it knows who I am and then it's able to render a view based on a known identity so because it is going haywire apologize I won't be able to show it but I am happy to open floor up for questions yes the third party scenario with mobile banking what do you mean handle it in what way the third party scenario is really relevant if the user excuse me let's say that the the identity source of truth is Amazon for what better Facebook right they claim that they're their identity source of truth and your I don't know maybe you are the bank and you want the user to login with Facebook the bank has to open up a pop-up window or do a redirect to send the user to Facebook and then Facebook asks the user hey Bank of America wants to see your email address in your first name and last name are you going to allow this and if you say yes they create an identity assertion a JWT and redirect but that user back to your website with that identity assertion and then that assertion is verified it's sent back into your server as Bank of America and then Bank of America has what they call an out-of-band connection direct between the bank and Amazon and they'll take that token or that assertion and send it to Amazon and Amazon says okay this is the assertion it's valid it does represent this user so now here's the data that the user has given you permission access and then you can trust that that user has effectively logged in through Facebook so I want to be super careful that is not single sign-on that's what I call delegated authentication right single sign-on is a different ballgame it's very easy to get the two confused but but that's how that would work in the three party scenario does it you know any other questions yes a recommended Java library for doing auth and stuff well there's there's a couple of them so Shiro does not yet do it but it will be part of the to Dido spring security kind of does it but it doesn't in via delegating these other libraries and from what I've heard it's kind of complicated and difficult to use I can't I'm bummed because I can't demo with this but storm path we have a library that automates all this stuff you literally drop in your class path especially with the spring boot up and it fires up and the OAuth token endpoints there your login pages there your registration pages there you have to build any of that stuff so clearly I'm biased I highly recommend that you at least try that out because it is free to use so it's no no sweat - to give it an evaluation but we automate all that stuff but maybe more interestingly is that all of our SDKs are Apache - open sourced so if you want to see how we're doing it you just go look at the source code and get him any other questions yes well yes it would happen on your machine but as you saw when I entered in the like in the Google example and I typed in the script that gave the alert hello world that JavaScript is now executing in your browser in the context of your Dom right and that JavaScript it maybe it wasn't alert maybe it was something that sends an HTTP request after reading all the cookies that you have on your machine and then sending it off to my website so I can steal your identity from the website that you're currently on right that's really the danger and cross-site scripting attacks is once you get once the the JavaScript code executes in the context of that Dom environment it can do whatever it wants to the at least the JavaScript engine allows and it could run as natively as any other script that you loaded from your website so it could be very dangerous and depending on what the script does whether it sends a lot sending off a request or snooping around your data you know maybe it waits for a certain page to be loaded so that it can see your credit card information you know like yes it the attack only affects you as an individual but it could it could do a lot of damage that make sense so the in both generating a JWT and looking at a JWT if you're using signatures which everyone really should be if one when dealing with identity assertions the Builder needs the key so that when it spits out the string it can create the signature that's appended number you know the three parts that third part is the signature that it sends along with the rest of the data as part of the JWT now what the server does is let's say the serve the client sends it into a server the server will then look at the whole JWT and it kind of takes that signature and chops it off and kind of saves it for reference and then it looks at the first two parts and it looks at the signature algorithm and there anything else as well as maybe an identifier as to what signature key was used to create it and it will repeat the process of what the client did it'll it'll take all that data base 64 encode it send it through the signature and then it checks is the signature that the client sent the same thing is what I calculated if the two are identical you can guarantee that the payload hasn't been changed right so whoever creates the JWT has to sign it and send it you know and then the receiver needs to verify the signature is the same as they compute it compared to what they received from the sender and if those two match then hasn't been tampered with in transit now that doesn't mean that hasn't been seen by third party it just means that no one's changed the payload yeah any other question Jess no so the question is is with regards to JWT is it meant for any other third party API or is it meant just from my client to my server right the question and the answer is no it can be used for any protocol anywhere that needs to do any type of assertion it doesn't even have to be an identity assertion any client or server that understands the JWT concept and can do signature verification or decryption if it's encrypted can find value in this approach not necessarily so the example I was showing you was using H Mac as a signature algorithm and H Mac requires a private key that's not shared with anyone else so in that world the server generates the JWT sends it the client and the client has to send it back unchanged and the client will use the same private key to verify JWT also supports public private key cryptography where the server can generate a key and send it out and the public key can be used to verify it right and the public key could be used to create a signature and sent it in and verified with the private key so you can use it in that public private key exchange kind of mechanism images and assets absolutely and that's usually typically ok like most JWT s are less than 512 bytes to 1k and they don't materially impact a lot of the requests that go out a lot of them can be to 300 bytes you know so it's not as long as the quantity of data you store in the JWT you get your work done is relatively slow or small it's way more efficient than having to cluster sessions for example yeah so it does add some network overhead for sure but I think the trade-off is that you don't have to worry about server state and that allows you to scale way better than otherwise yes so the question is is that using OAuth 2 with mobile clients they have refresh tokens that acquire new tokens new access tokens you know if you have a single page application could you use them in the same way right what I recommend it um yes I would actually recommend it as long as you're using HTTPS Everywhere right and you're so I'm a security nut right so like TLS is not as I mentioned not a panacea and so one of the things a lot of people don't understand or or recognize with SSL is that it's a network layer Network layer protocol right so if I have data that's in my app tier and it goes down the application stack to the operating system down to the network here and then across the network and then out of that up the application step into the other app these two parts are not protected at all by TLS only the network transmission is so if either machine has a virus or a bug or trojan that data is still susceptible to inspection and infiltration my TLS doesn't protect at all against that scenario so the only way to protect n2n is to use message level encryption like a jwe that guarantees nothing in or out on the way down or across the network can be intercepted so I would recommend the mechanism you're talking about depending on the security profile of the application being built if it's a banking app probably wouldn't do it if it's a social app I have no problem with that so it really depends on on your app like yeah does that answer your question yes so the question is is that a high level can we talk about a migration path between existing session mechanisms to a JWT based solution this is actually it's actually not that difficult so you can actually use both concurrently because the container Tomcat for example will translate that session ID and make it available as an HTTP session automatically if you set up like a servlet filter that will start inspecting these tokens as they come in then you can do the identity assertion at that level and then set it maybe as a request attribute like the user account and that will just follow the request during its during its execution and then so that allows you I think to migrate from one to the other one of the other things that I like to do to in those scenarios and I think you know Shiro has a solution for this is for the servlet API I'll put in a servlet filter at the top of the stack that wraps the httpservletrequest and it prevents anyone from calling yet session or get session true or just get session without any arguments and that will guarantee that anything below the stack that tries to do that will throw an exception because that means that somebody's trying to create server state and they shouldn't be allowed to do that and so that's one of the nicest ways to catch yourself and any code that you might have missed or forgotten about because it'll show up as an exception that you can catch hopefully an integration testing so that that's probably the cleanest easiest way to support that and then as long as your servlet filter mechanism so storm path and shear like storm paths stuff is all based on several filters will do all this resolution before it ever gets here your your controller your MVC controllers such that you can call requests I get account and it just works because our filter executed before it got to your controller so that's why we do it and that's why I'd probably recommend to do it because it worked fine for us any other questions um the question is do we work with clients on migration scenarios the answer is yes if they're going to be using storm path in their products deck yeah most definitely we help try to automate all the OAuth flows because our back-end team is a is a very senior Java level team we and if any of our customers using any of our Java integrations those are always very easy for us to support we also have for each language we support we have an on staff dedicated employee that is an expert in that respective community so they can we have a job you know Ruby guy who knows that stuff like the back of his hand and he'll facilitate with that kind of integration so but if you're a Java back-end we have a whole swath of people that that that help on those kind of things it's pretty easy for us to support thanks for your time guys you
Info
Channel: InfoQ
Views: 42,151
Rating: undefined out of 5
Keywords:
Id: sv0TUiYVimw
Channel Id: undefined
Length: 68min 35sec (4115 seconds)
Published: Mon Jul 20 2015
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.