Introduction to OAuth and OpenID Connect | Developer Day 2021 Labs

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
let's go ahead and get started thank you all for being here so the first thing i want to start with is a bit of uh background on oauth and openly connect i want to talk about um some of the some of the history some of what oauth is kind of set the stage for that and then we'll get into the how it works part of it so if you haven't yet made your own developer account this is a great time to do that while i am giving this background information uh so the spec the oauth spec is not a great way to learn this stuff it turns out the spec is more of like a reference guide and you really have to know how to read specs before it's even useful there's a lot of terminology in there that's pretty confusing and um it takes a while to understand how these things work oauth is also not even just one spec oauth is quite a lot of specs all put together and some of them aren't even some of them are even made by different groups and different uh organizations so it's a pretty big mess to try to sort through on your own and that's what i'm here to help sort of help with is i want to give you a path to find your way through this this mess of a maze so i want to go a little back in time first and talk about why we have oauth to talk about originally the problems that it solved and i did mention this a little bit in the uh the video in my session yesterday at the developer day conference conference day um that video will be available very shortly on youtube so if you do want to go uh watch that back later that'll be on the octa developer youtube but this used to be a very common pattern on the internet which was how things worked before we had oauth the um the application a third-party application like yelp would launch and it would say hey are any of your friends already using yelp and to do to find that out we're going to say uh is we're going to the application would ask you for your password to your email and then it would go sort of log in as you and go download your contacts and see if that uh see if that would you see if any of your friends were already using the the app right so it's not a great solution because it means that what you're doing is you're basically giving the credentials to your account to some random application like yelp or facebook everybody was doing it and the uh this has many problems right i don't want to go around giving my login to my email to random apps because it means it can do anything as me and i don't necessarily trust it that it's going to do only what it's promising it's saying it's going to only ask for my contacts but there's nothing actually stopping it from accessing the actual email on my account so this is really the sort of origin of what oauth was uh trying to solve which is how do we let application and it started as this uh third-party app access of yelp is trying to access data in google or last if i'm trying to access data in spotify uh buffer trying to post into your twitter account whatever that might be you know third party uh one one company's application talking to a different company's api and that's really how how it started because it was clear that we didn't want to share passwords with these third-party applications that kind of led to this use case of these sort of sign in with x buttons and this was not necessarily the original goal of oauth this was not what oauth was actually intending to solve but people ended up repurposing it for this because they saw a sort of way to kind of make that work sort of i'll talk about the sort of i in more detail later so what's interesting is that there's actually nothing in oauth that talks about who the user is that was all added later by openid connect so again getting back to the oauth part i like to think of it as this analogy of checking into a hotel where you go to the front desk you show that person at the front desk your id and credit card and they give you back this hotel key and then uh you go to the door and you swipe the key on the door and the door lets you in now this is exactly analogous to oauth and what's interesting about this is that the door doesn't need to know who you are the door doesn't actually care about the identity of the user who's going to be using the room the door just cares about whether the key card is authorized and i want you to remember that when we talk about oauth access tokens access tokens don't represent that a user logged into something access tokens represent that the application is authorized to access data so it's a slightly different problem and it's i know it's a little bit confusing but open id connect is the other half of that picture openid connect is explicitly a way to say this user logged into this app at this time and that is where the user information is provided in uh through openid connect the good news is openndconnect is built on top of oauth so actually once we learn the foundations of oauth opendconnect is not a lot of extra stuff to add on top so we're going to start with how oauth works by actually walking through a flow and then we will also talk a little bit about openid connect if we have time for that so the first thing i want to do is um is the uh i want to talk about some of the terms you will find in the flows and in the in in as you are going through and using this stuff these are these are the roles in oauth so we have users who are going to be using an application through some sort of device a phone a browser right and then eventually that application is going to make requests over to the api now the api is um in in oauth terms it's actually called the resource server these things have terms in oauth that are confusing compared to what you would say in a conversation but there is a good reason for it but defined that way but not really important for for our purposes the thing that's missing from this picture is the thing that's going to be actually creating those access tokens handing them out validating users getting users to log in all that stuff around the sort of user management that is where that's the job of the oauth server or the authorization server so in uh this is the complete picture we have users which are who are called resource owners in the spec using devices or a user agent uh to access an application that applications one's trying to get the access token because it's trying to get data from the api now what we're going to talk about for the most part in this workshop in this lab today is how these two pieces talk to each other how the application coordinates with the oauth server to both to sign the user in get the access token and we're not really going to deal with the api yet because that is a job for the afternoon so we are ready to start this and to um to sort of set things up because i want to give make sure you have a chance to actually try this stuff out we're going to dive in and i'm going to do this first part of this uh workshop live with you and uh try to make sure that we are uh we have everybody keeping up so back to the uh back to if you scroll down you'll notice there's a link to this document preparing for the exercises and i will also drop a link to this in the chat room but it is down at the at the bottom of the page as well this is what we're going to walk through first and i'm just going to go through it live uh with you right now and please do try to follow along um and we will what we're going to do right now is basically set things up we're going to be able to set up the octa account set up the um the the oauth server in order for it in order to be able to use it for the next exercise where we're going to actually do the oauth flow uh i've seen some questions in the chat um got an octa account to watch this presentation got it i'll see your account see this thread where else do i need to get an account that should be it eugene um the octa account is uh what you'll need in order to follow along with the steps i'm going to do um the off zero account it's not don't really think of it as an auto account it's just how you got into the chat room um you don't actually get any permissions to do anything in not zero other than just joining that chat room that's a an organization i set up as if i were a customer of off zero in order to get people signed into the chat um okay so and then there was another question oh the slide deck um i will post the slides afterwards yeah but the um the pdf that we're looking at right now or the dock that we're looking at right now is what you'll need to follow along with the exercise so we are going to go ahead and get started i'm going to make this bigger so i don't there we go uh step one is getting your octa developer account so this is um hopefully you've had a chance to do this ahead of time um because this does require like sending an email clicking on the link from the email so it takes a minute um but it's not it's not that long of a process anyway once you are logged into your octa developer account you're ready to actually configure it um i should also mention that for the purposes of this exercise as well as the uh one in the afternoon generally anytime you're doing these sort of trial things where you're following somebody else's instructions it's you should usually a good idea to not do that in your own production environments please do it in a development environment that way you don't risk messing anything up and i don't have any sort of security issues around that so i have a i've created my org it is um it is this i have a custom url mine yours will end up with just some numbers on it but i'm ready to set this uh set up my octa org for completing the exercises i'm going to give this split screen so i can jump to switch back and forth all the time if you are looking at in a smaller window the navigation bar on the side is collapsed i've seen some people get confused about that and think ask why they can't find it so that is where it is it's in that little collapsible hamburger so first thing you want to do is go to security and go to api and this is where you're going to sort of set up your oauth server and tell octa how you want it to work there should be only one by default um it'll have some random numbers on it um maybe i should just go over to my account that has the random numbers um let me see if i remember what what account that is because maybe this one will work yeah great okay get rid of that one i'll bring this one back okay this is more like what you're going to end up with on your account security api default i have one os server it is just the default oauth server that's um how it works at the beginning so this is the page that talks about like okay here's my server here's the audience for it here is uh the issuer now the issuer is this is this an important uh idea of this is the identifier of the server so this is this does a couple of things it's um we're going to need it in order to verify things in open connect later but it also is useful for telling the application the auth app how to find the various endpoints in the server so if you notice this metadata url down at the bottom it's actually the issuer url with this extra thing tacked onto it here so and if you click that this contains information about the server like what things are supported and these urls these are the urls we're going to need later so that's just keep that in mind that's how you find the information about your oauth server so we're going to go copy this and write it down because we need it later so i'm just actually going to open up um i'm just going to open up text a text editor uh just so i give myself a little a little scratch pad okay make that plain text so here i just have a little scratch pad so i can keep track of this stuff issuer url now what we have to do um in order to sort of do an oauth flow is we actually will need to ask for a scope i'm going to talk about scope in a little bit uh for now what we're going to do is just go ahead and create one so i'm going to go to the scopes tab and looks like i have a couple of test ones in this one delete these okay so we're going to go add a new scope and we're just going to call it uh developer day and click this box include in public metadata so what this is going to do is it's going to give the app a scope that it can request at this point you might notice there's also a bunch of other scopes in here all the open connect scopes these are the ones that kind of are shipped by default and these will tell the oauth server or these are built into the oauth server so the app can request things like the user's profile information or the user's email address we'll get a chance to try all that out um okay once you've done that you're ready to sort of check your work so um what you can do is go to this website oauth.school and click on the getting started which i will drop this into the chat again so there's the introduction exercise what this is going to do this is a tool for this workshop that is going to let you check your work and see how far see if you've done things correctly so what we can do is if we've set things up properly we should be able to get green check marks on this step so i'm going to go back to my oauth server and copy that issuer url paste it in here and cross my fingers uh okay so what it did is it verified that there was a custom scope that i added and now it's asking me to find my authorization endpoint and token endpoint so these two are the urls that the oauth application is going to send the user off to or go get access tokens from and we'll walk through the flows in a second where you'll see how these things are used the authorization endpoint think of that as the one that the user interacts with and the token endpoint is one the application interacts with so how can you find these well it turns out that is part of the oauth metadata so if you go back to this metadata link which again i found from the issuer url down here go find the metadata link there's actually two urls up here authorization endpoint and token endpoint so we're going to copy that paste it there we're going to copy the token endpoint and paste it there and we're going to check the work and i have in fact completed the exercise okay so um if you are getting an error before this the error is probably because of the scope step um i kind of went quickly through that let me go through this again if you go to scopes add a custom scope you do have to check the box include in public metadata that's important because that's how the this tool can actually check that you've created the scope what what that actually does is if you go back to this metadata document see how there's a list of scopes supported if that public metadata box is not checked your custom scope won't appear in this list so uh it contains all the openid connect scopes by default but i've created my custom scope and then put it in this i put it in the metadata so that the the tool that's checking over can actually see it there so that's enough to complete the exercise but let's go back and talk about what's going on in some of these things because i kind of just threw a bunch of stuff at you really fast so let's go back and talk about um let's start with the uh with scopes so scopes are um scopes are something that um are mainly used for um the wrong i have the wrong slide deck that's what's going on so scopes are what a uh from the applications point of view as the app developer you're not really going to be worrying about um designing scopes you're pretty much going to say you're going to say oh i'm trying to use this api and it's telling me that i have to request a certain scope if i'm going to be using these kinds of um these kinds of endpoints so you might see that on let's actually just go look at the github docs so github oauth scopes and if you if you look at this um github has a long list of scopes so notice that they are uh sort of they give access to different groups of things so there's like the reposcope if you if you do an oauth exchange with github and you get an access token and you don't request any scopes it won't give you access to any of the actual api endpoints so if you want to be able to read and write code in a repository then you'll need to request that scope and then the access token will contain that scope so these are all defined by the uh sort of defined by the oauth server and as you're developing your apis you'll be responsible for creating these and deciding how they work and we will give that a shot in this this afternoon in more detail but for now um as an app developer just know that you need to go and figure out what scope you need to request before you can actually go and use and use a use an api endpoint okay so that's scope let's talk about the endpoints the authorization endpoint and the token endpoint so the the two the two endpoints are there's two parts of of the oauth flow generally there's the part where let's go back to this picture um there's the part where the application says hey i'm trying to get someone to log in and then after they do and it gets them back to the app the app is ready to say hey i want access tokens now so what this really means is it's the um the os server has two endpoints that it has the authorization endpoint which is sometimes that slash authorized but depends on the server and there's slash token so this means um the the this this uh application is going to first redirect users to the authorization endpoint and then it's going to make a post request to the token endpoint so let's go walk through let's go walk through one of the flows uh step by step in slide form before we actually go and try this by hand okay so we're gonna start with the authorization code flow with pixy so okay authorization code flow you've probably heard of that is the sort of um default normal flow whatever you want to call it uh and that is if you uh if you're doing an oauth flow from most kinds of apps you'll end up doing the authorization code flow the pixie is a extension it's one of those puzzles in the maze of uh extension to oauth that talks about uh it adds some extra security to protect the flow we're going to look at the whole flow including pixie uh step by step right now before we actually try this uh on our own so across the top we have our our roles that we've talked about of you know the users interacting with this application and i do want to just again reiterate uh most oauth clients will use this flow mobile apps single page apps web server based apps those are all possible to use this flow with no changes to the flow there will obviously be differences in how they will do the different parts in terms of where they're going to be storing things but the flows are actually the same so it is auth code flow plus plus pixy so this starts off with the user saying i'm trying to use the app that's them clicking the login button so the user says great trying to use this app here we go um the app says hang on uh we're going to generate a new secret for this flow and calculate the hash of it and this is the first part of pixie so what this is doing is basically the app is creating a random string it's and then uh the hash is a one-way operation so for example if i told you think of 10 random numbers writing down a piece of paper keep that secret but add them all up and tell me what they add up to i would not be able to tell you the 10 numbers on your piece of paper because it's a it's a one-way operation now in practice we use better hashing algorithms than that but same idea the point is that even if somebody had the the hash they won't be able to reverse engineer it so okay the point here is that the app has something secret that nobody else knows right now so the app then tells the browser to go to the oauth server go to the os server so that i can get the user to log in this is the first message that the app is sending to the os server so this is really all it's doing is just building a url telling the browser to go to that url and then lands at the land the user will land at the oauth server so this is not something that the application the application is not talking to octa directly talking to os server yet the application told the browser to go talk to octa this is where the user logs in if you've configured the consent screen they will get a prompt to approve the request and then instead of returning an access token the oauth server says hey here's this temporary code for the app and again this is not returning directly to the app this is being sent from octa through the browser to the app okay now we can finish the flow so this first this first one is the authorization endpoint that's the authorize stage then the app can talk directly to the os server to the token endpoint and say hey here's a temporary code i got and so that you know that this is the same piece of software that started the flow here's also this that secret that matches that please give me a token the oauth server can calculate the hash of that secret itself because it's a one-way operation so you can repeat the operation but you can't undo it and then what this does is it lets the os server know that so here's that second request this one is to the token endpoint so what it does is it lets the oauth server know that the same piece of software made the request started the request of the authorization endpoint and is the same one i'm talking to the token endpoint and now the app has the access token and the flow is done and we can move on and the app can go and use the api so this i i often hear people ask why is there this extra step right why do we have this temporary code why do we need that why can't we just send the token back directly and the key thing the key reason for that is because there isn't a direct link between the application and the oauth server at this stage there isn't a direct link and instead what there is is a is the app is talking to the os server through the browser that is what we call the uh front channel so i'm gonna talk about this really quick the back channel is the sort of normal way of what you think of when two pieces of software talk to each other over the internet it is a post request or a get request actually uh it is an http request that uh that covers both of them it is an oauth has to be sent over https otherwise there's a lot of problems but the point is that it is an http client talking to an http server this gives you a lot of very useful properties like the request can't be tampered with you know where it's from you know who got sent to you know it wasn't modified in transit the front channel is when two pieces of software talk to each other by using the address bar of a browser so that there is no longer a direct link between the two pieces of software so i like to think of the back channel as hand delivering a message where you can walk up to somebody give them something you can see who they are they can see who you are you can see that nobody came in and stole it out of the out of the middle sending data via the front channel is more like putting your message in an envelope and sending it in the mail where you've handed it off to somebody else to deliver and uh then it will hopefully make it there but uh maybe it may or may not you don't know you've lost the visibility because you've handed your message off to somebody else to deliver so that's the difference the um in our in our flow in the sequence we just talked about what we've done is we've used the front channel for this whole first half of the flow we've used the front channel to have the oauth client start the flow by directing the browser to the oauth server the oauth server then sends that temporary code back through the front channel now the problem with the front channel again is you've lost visibility in terms of whether you know the message was sent or received so if you've sent a message in the mail you don't know if it made it there and if you receive a letter in the mail you don't know who it's from you can't prove it that's the problem so we have up until this part of the flow where we're just at the temporary code issue uh point we don't actually know if uh we don't actually know if any if there's been a hack yet we can't tell if uh if there's been a problem so the os servers issued this temporary code it hopefully landed at the right app it may not have so we use the back channel to sort of fix that up plug it up using that uh temporary secret that i made up at the beginning of the flow okay that's enough diagrams let's try this stuff out and actually see how it works so for this one i'm hoping people got a chance to uh finish the getting started exercise uh let me know what i'm gonna do actually i'm gonna do i'm gonna put a message in the chat um i'm gonna say i'm gonna i'm gonna put a message and say click this reaction if you um have finished the exercise so have you uh finished the getting started exercise i choose a reaction and um go ahead and click the uh let's see check for yes and where's that red x there we go okay got a bunch of people who are good to go fantastic so let's go ahead and um yep okay we finished that close that one so here is the other link i'll drop this in the chat and should be able to load that up i should make sure it's also on the web page so okay we're going to why is why is it so narrow there we go all right sorry about this okay now it's on the website so what we're going to do is walk through a complete oauth flow and do what we just talked about in that sequence diagram by hand now i do want to caveat this with uh most time you are writing software to do this and you're not going to be doing oauth flows by hand the point of this exercise is to show you actually what the software is doing under the hood so most of the time you're going to be doing you're going to be grabbing a library that you that implements oauth or implements specifically a provider like octa or auth0 dropping that into your application and magically everything works hopefully that's the idea with the library and that's great and definitely should do that if the library is available if there is no library available for your particular framework or language or whatever that is or if you are trying to create one of these libraries then that's really that's when you're going to need to know exactly the step-by-step and the low level so that's what we're going to do today and we're going to do it without writing any code because i don't want to i don't want you to have to be learning some environment or language in order to follow along with the concepts because there's actually not that much going on when you when it actually comes down to it so the uh the goal here is to show you at the lowest level what's happening when you're doing one of these oauth flows and hopefully that will give you an idea of when you're looking at a library giving it give you an idea of what it's doing and how how it works so that you can better troubleshoot errors because i know from experience that a lot of times once you encounter errors with these libraries it's it's often just like you have no idea how to fix it because there's no you have no idea what's going on under the hood so we're gonna hopefully shed some light on that here uh okay so i'm gonna go back to here um if this website doesn't store anything like in its server so if you've closed the tab it may have forgotten your getting started progress so make sure you have a checkbox there before you continue um and for people who have joined late let me drop that link in again so we're going to do oauth for web applications next and you might notice there's a bunch of other ones here as well uh it turns out that there's actually not a lot of differences between these two so don't worry too much about it so okay there are again basically two stages in the oauth flow there's the app decides it's going to start the flow so it has to create a url to send the user to and then it's going to wait for the user to come back to the app and it's going to go and try to get an access token so we're going to do those two stages here okay make sure you've started the getting you've made sure you've finished the getting started exercise because you need those things we wrote down first um and i've got my little notes here uh as a scope i created was called uh developer day so let's write that down so i have it handy next thing we need to do is go and create an application in octa so we're gonna go back to the dashboard open up the side menu click on applications click on applications again and now we can go and uh create an app looks like i already have a few in here so i'm gonna delete these um so that we don't get confused okay so i'm gonna go click on create app integration from this pop-up i'm going to choose open id connect again remember how i mentioned that openid connect is built on top of oauth well most of the time the app does want to know about who the user is so most of the time we actually do want to do an open connect flow as well but you can click that and then still do plain oauth if you want for this exercise we're going to say that we're building a web application so that's any time the app is running in server-side code so go java asp node php if you were building a single page application that's going to be running in the browser then you would choose this option and that's going to set a bunch of different settings internally in octa like set up cross-origin resource sharing policies things like that if you're building a native application which counts both apps running in a desktop environment as well as mobile um you would choose that option and that also applies notice that there's this example of react native because it is uh also possible that your native app might be written in javascript but if it's running in a desktop environment that's the important part so it's where is the app running so for this purpose we're going to say it's a web server based application we're obviously not going to actually put it on a web server but we're just going to see how this works okay next we have to give it a name the default name is fine i'll just leave that alone there's other settings in here like a logo sure um notice that there's a bunch of different grant types we've only looked at the authorization code grant type right now because that's the most important one but if we do want to talk about refresh tokens later we'll come back and check that box so okay the important setting to change here is the redirect url this is the list of urls that octa is allowed to send the user back to after they sign in so the flow again is the user's at the application they click a button they get sent to octa now their browser is on octa they finish logging in they have to get sent back to the application that's the redirect url there's a lot of sneaky hacks that are possible if there is not an explicit list of urls here to protect uh the the user so if you don't uh if you if you don't have a list of these and octa would send the user back to anywhere it becomes very easy for attackers to steal things and confuse the system so we're going to put in this link which is exampleapp.com redirect example hyphenapp.com redirect that is a website i've created to help with this exercise so it's in the it's in the document copied out of there this is when you're ready to actually go and build you know write code then uh you would obviously use the url at which your app is running and uh you can add multiple which is useful for example um if you are doing if you want to use the same application for development or testing or you're testing on localhost and you want to test on a development server things like that um but generally you'll probably end up having just one in in production um and the restless oh we do need to check this box which is who is allowed to use the app just allow everybody it signs it to that group and then anybody in your org can use it there's probably only one user in your org right now because it was a brand new org so check that box um okay now we have registered the app what this does is it gives the app its own identity in the oauth server so we are able to now have a record of for example this user logged into this app or we can configure policies based on the application like who is allowed to use it or how long access tokens should last for particular apps and things like that the app needs its own identity the app in this case also has its own password that's what a client secret is basically the app's password it's how the oauth server can um authenticate this application when it's making requests in the back channel so we're going to copy these down here because we're going to need these later so client id um [Music] and then client secret wow i can't type today secret and uh i think that's all we care about right now great so with your credentials ready you are ready to start the flow now we're going to start putting pieces together so to start the flow we basically need to create a button on a web page that's the user can click to go and log in that button needs to send the user uh to the to the oauth server um alyssa asks what should we select for controlled access again uh was that what that was called um oh it's only in the it's only in the create flow so if i go back to create app integration web application assign oh i just wow i've never read that label before um everyone just choose everybody if you uh don't do that you'll get an error when you try to log in so just make sure it's set to everybody okay so that's created um what we need to do next is craft this url the url is the where we're going to send the user to so we need to send the user to the authorization endpoint remember the authorization endpoint is the one that the user interacts with the token endpoint is the one that the application interacts with that's front channel versus back channel so we need to find the authorization endpoint how do we do that um it was here in this metadata so again to find the metadata link you go to security api click on your oauth server and the metadata link is here this is also possible for an application to find programmatically because you can take the issuer url and add on this path which is in a spec and then you can find that link so the metadata link looks like this and here is the authorization endpoint so i'm just going to copy that put it down here and we're going to start building the author the authorization url um okay before we do the um before we do the pixie bits let's create the rest of this and i'll talk about these parameters in the in this in this document the authorization url we need to the app is basically telling the oauth server what to do like what it's trying to do so we're saying response type is code which is we're doing the auth code flow and then we say uh which app is making this request that's client id we can copy that we need to tell the oauth server where to send the user back to so we include that redirect ui which is i have it in this tab here uh redirect uri and what else is in here uh scope we need to request some sort of scope for now we're just going to request developer day and then because we created that up at the beginning we need a random string called state and for this i can just type in some random numbers and now we need to add the pixie parameters pixie parameters are code challenge and code verifier let's talk about what those are um i again created a helpful tool for you but you're welcome to do this in any in code or in any language you want um copy that link there we go so exampleapp.com pixie and what this is is a um it's basically a javascript implementation of the pixie functions that you need in order for it to work so we've got um two functions we've got a random string generator and we've got the hash function and if you actually go view source of the page you can see it it's down here so here's the generate random string in javascript here is a shot 256 hash function in javascript um but you can use this to get what you need you need a random string we can just generate them all day long it's not storing anything it's just doing this on the page it's just for troubleshooting um and then once you have your random string which is called the code verifier you can calculate the hash of that which will appear down here now if you are trying to write this code yourself the most common problem i see people encounter is their hash function in their language outputs hex digits rather than bytes if you take the hex digits and then try to basically four encode it you're gonna get some random thing that's not at all right you have to make sure you find a shot hash function that outputs raw bytes and then basically four encode the actual bytes so in javascript there's a way to do it which is i don't remember the api it's been so long since i wrote this um oh it looks like the default uh the default encoder does return the raw bytes um in php there's like a parameter you have to add on it so just double check that the function you're using for calculating the hash outputs raw data not hex encoded data and then you basically form url and code that so here are the two strings we're going to use for the exercise code verifier it's just a random string it has to be a certain length so this generates something in the middle and then there is the hash of it now again the point of the hash is that it's one way so if you know this value you can't figure out that one but if you see this value you can calculate this one so the hash is what we're going to include in the url because the url is something that's being sent in the front channel in the browser where we don't know who's going to see it so we can add code challenge and we also tell the server code challenge method is s256 that's how we hashed it um okay so let's these are getting small this looks good i think that's everything um just for fun let me make an intentional mistake like use the wrong redirect url i'll take that one out and let's see what happens when there's an error with this request so okay this one was bad enough that we didn't even get a single message um there is something wrong with this url and octa just says bad request uh what's wrong with it actually i see there's a problem there's an extra space this keeps happening to me when i copy these things there's an extra space up there in the client id okay now we're getting a more helpful message now that we have an error now that we have a valid client id so now we're getting a message saying the redirect url is wrong with basically what that's saying and that's because i have the wrong redirect url in this request so let me get rid of that space so i don't copy it again and then if we include the actual correct redirect url then what's going to happen is we will no longer get that error message however i want to show you this in an incognito window first so if i visit that url and uh in an incognito window i'm not logged in here so octa's asking me to log in if i visit it in this one i am logged in so it's going to do something different um okay so for the exercise where's my oauth school tab okay what we're going to do is we're going to paste this url in here because this is going to do some debugging on it to tell you if you've done things wrong for example let me mess that up and run this yeah it looks like you're missing some query string parameters so double check that you've got everything in there and it looks like it's correct this can't know if your code challenge is right yet because it doesn't know what your code verifier is so again if you've calculated the hash wrong this might look okay and you'll fail in the next step um okay so let me pause there i see some questions um what about state you don't really need it state is a good question a little bit of backstory on this um before pixie existed the uh the problem is that let's see let me click this login button okay so what happened is this this link actually takes me to octa right you can see it is this url and it opened up in a new tab and you didn't even see me at octa because i was already logged in and i got redirected back immediately this is this redirect step now here's the problem and here's what pixi is solving which state attempted to solve sort of this link anybody can visit this link right i've got a redirect url on the internet i i'm not logged into this app yet because i'm trying to log into the app and there's a code up here which the app is going to try to exchange for an access token and uh the problem is that this app um if i just type in junk it doesn't know whether it's real or not right so it might try to go and exchange that for an access token at the oauth server um sending junk to it's one thing the more significant problem is if you can sort of like swap authorization codes between valid users in the middle of flows which is definitely possible um that's what state is trying to solve basically what the state does is it means that um i can no longer make arbitrary requests to this endpoint so if we didn't have state here and we only had code then anybody could just come in here and be like oh well let's just try this one see if that works and it would go and make a post request over to octa to exchange that that's not great so what we do is we have state and if i don't include if i include a invalid state parameter this app can then check to make sure that it was the state parameter that it generated before it goes and exchanges the code so that was what state tried to do that also has some problems there are still some attacks you can pull off even with that mechanism in there um so then a few years later pixie came in which actually solves all of that so now with uh state and with pixie if you were to try to swap out somebody's authorization code the next step would fail because of pixie um that is way too much to get into to try to demonstrate that but we do have a video on youtube on the octa developer channel called authorization code injection this one um i'll just drop this link in the chat as well that is a demo of the exact uh the exact step-by-step of how to pull off that attack and why pixie solves it so if you are curious about the details feel free to watch that link um okay so state is sort of just like a first filter um oh and jan says doesn't state also present csrf and replay attacks um yes again it helps and it uh it's not necessarily a guarantee pixie does everything the state does but better so um the the state parameter um it's still good idea to do it because again you generally you want to add layers of security and not rely on just one piece so it's like a good first pass at a filter to reject certain junk requests but the uh pixie is the one that's doing most of the work of protecting against code injection code swapping as well as csrf um okay so uh rachel says do we not need scope you do need scope let's see what happens if we don't include scope in the request i'm going to take it out of this url scope we'll take that out and i get so okay it's happened so fast it's so hard to tell i got i went to octa and i got sent back and instead of sending back a authorization code i got sent back an error message in the query string and this web page just helps spit out on the screen so it's easier to see but it says invalid scope the authorization server does not have any configured default scopes so this is why we have to go create a scope and then include it in the request and you can see it's down here it's in the middle of my list of parameters i use the scope developer day just because it doesn't mean anything right now but we'll get us through this first step um okay if i click on that link i get sent to octa and i come back and now i have an authorization code so what can we do with that um yeah first we're going to verify that the state matches the one that we created at in the beginning which it does that looks like the same number so we're good there and now we can go and exchange this authorization code um could you have used any scope for now uh you any any scope that you've defined in your oauth server yeah i i don't care what scope you actually define right now because we're not doing anything with scope yet um you just need something there okay so where are we on the on the dock here since you're already logged into your account you'll be redirected back immediately if you want to see what happens for a new user open an incognito you'll be redirected back here and sure enough we see that and if you've got the authorization code you're ready to exchange it for the access token so now we're gonna make a post request to the token endpoint this is you're welcome to do this however you want you can use curl you can use postman you can use code in whatever language all you need to do is be able to make a post request with some post body parameters personally i find uh postman extremely cumbersome it feels like it takes so much setup to make it work i don't think it's worth it so i'm not going to be using that i'm just going to use curl because it's already on the machine and there's not really anything to it um if you are but yeah it does not matter what you're using to make this post request the point is that this is simulating code that would be in your app's server making that post request if you are the if you're copying from this document be careful because sometimes copying out of these things copies weird empty characters like how i somehow ended up copying an extra space character um you it's probably safer to retype all of this and not copy and paste just because of the new lines issues and stuff so i'm gonna i'm gonna do this from scratch so i'm gonna type curl we need to know the token uh token request so where is the token endpoint again back to our metadata copy that um so curl token endpoint i must do all one line so we've got uh we've got let's just go through this list grant type authorization code that's how we know that's how we tell the oauth server that we're trying to exchange an authorization code there are other grant types for example the client credentials grant type when there's no user involved or there's the device flow for like a smart tv but we're doing the authorization code grant okay we need to then tell the oauth server which redirect you already used i redirect uri which i've got up here we've got um side note redirect uri in this request was another similar protection against trying to avoid these tricky swap uh requests which is now redundant um and pixie again does that job better so but it's just required because of uh most implementations require it because it was more or less required in the spec even though it's not actually really doing anything anymore um okay so those two uh next we have to include the app's credentials now there's multiple ways to include the credentials you can put it in the post body or in an http header um i'm gonna put it in the post body so client id which i think i have it up in this document here let's make sure i don't copy a space see it copied a space that's weird uh client secret this is the app's password remember how i said it's the app's password that means we do not want to use this if we are writing code in javascript or in a mobile app um okay that's uh and if we include the code itself we got from where's my redirect tab uh this one here is the authorization code from the return now this is not enough and i'll demonstrate what's wrong by actually making this request and we'll see what happens we got back an error from octa saying pixie code verifier is required um this error is technically confusing it's misleading because but the point is that this first part is correct pixy code verifier is required um so the what that's because when we started this flow the the front channel requested that the octagon from the browser not from the app contained this code challenge so we have to prove that the same thing made this request remember that the that octa is seeing these two requests from different places octa sees this request from the browser and octa sees this request from your app's server so they're coming from two totally different places how does octa link them up and know that it's okay to return the access token to the thing using this authorization code that's what the code challenge is for so the code challenge is that hashed version we need to send the code verifier from the server so if we go back to i had it here code verifier if i put this in the request this should now no longer give us the error of uh pixie code if i required and sure enough now we have a message that is the authorization code is invalid or has expired because it turns out these don't last forever they're short-lived one-time use codes so this authorization code we got has already expired because it's been several minutes since we've got it so we have to go get a new one so let's go back let's close that tab let's go back here um we've got the same authorization request right same code challenge that's fine and uh we're gonna go click log in it's going to give us a new authorization code and if we go and swap that out if we do this quick enough it should work and sure enough we've got the access token now to complete this we actually want to take this whole token response and paste the whole thing not just the access token but paste the whole thing into here and this tool will tell us if we've done everything right and we did um it actually goes and checks to make sure that the access token is really valid and checks to make sure it's got the right scope and all that stuff that's what that tool is doing so if you had any problems or missed any steps it would have told you um but again that is why you only want to do this from oh or as you're using that you've created specifically for this and don't put real access tokens into this please um okay that is that is done let me take a look at some of the other questions coming in um yeah some more questions about pixi versus state the uh so there are a couple of uses of state that are possible still uh that are useful and the one of the other reasons state is in there is so that your application has a way to persist data between steps without storing things in the app now that's not necessarily a useful thing for you because in many cases you'll be writing code that uses server-side sessions or encrypted cookie sessions in which case you already have a place to store things between requests when the user leaves and comes back because remember the user is leaving your application and then coming back to your application later and if you don't have a session or cookies or anything then you wouldn't know that it's the same user coming back so that is one thing you can use state for is to actually sort of use that as the way that you're persisting data between requests if you're doing that you have to make sure you are encrypting it or signing it in in some format so that you can you know it's not been tampered with but that is a possibility i feel like the vast majority of the time it's easy enough to just use the framework's own session mechanisms to maintain that data in which case you don't need the state to actually store that data but in that case the state is um i'd like to think of it as a first pass filter so again if you have a redirect url uh if you have your redirect url here and if you were ignoring the state parameter then what that means is that um your application might try to do stuff with the authorization code even if it's being thrown junk however if you are doing pixie pixi forces you to store that code verifier in your application logic somewhere which means you've already got a place to know whether or not the browser that's returning is the same one that started and then you're not you don't have that problem that's what i mean when i say pixie kind of makes state irrelevant uh in most cases because you're going to have to persist that code verifier somewhere if you really wanted to get fancy you could encrypt the code verifier and put that whole encrypted string in the state parameter however i don't see a lot of people doing that i would go through several audits on whether that's actually safe to do before doing that in production but they're um it's at least theoretically possible to do it in a way that makes sense uh but yeah that's for the vast majority of the cases um you if you're doing pixie you're you're going to be storing that stuff on the server-side session uh or even in a in javascript in the javascript application context wherever that is going to be then i that already gives you what you need in order to know that you can't you're not going to be accepting unsolicited requests to your redirect endpoint um okay so how are we doing on on getting the access token you should at this point be able to uh this is why i keep this in a text document take the authorization url visit it go log in get the authorization code make the request with the authorization code and get an access token close that one check the token and we're good cool okay um we've got a little bit of time left so let's do um oh this is a great question do we really need to include the client secret when using pixi i'm glad you asked that question um the answer is yes so pixie and client secret have nothing to do with each other they are completely different issues they are both protecting things but they're protecting different things now so pixie is protecting um against csrf attacks which again are even a problem with the client secret because he's also protecting against authorization code injection attacks which again can also happen even if you have a client secret and that video i linked above in the chat is a demonstration of that the client secret is how the app authenticates itself to the token endpoint that is only possible in the case that your application can protect the secret if your application can't protect a secret then it can't use it for authentication apps that can't protect a secret are going to be javascript apps mobile apps desktop apps any kind of any time the code is running in an environment the user controls so think just think about client secret versus pixie as completely separate issues they're not connected i know it's a little bit confusing because of sort of because of the way that pixi evolved and because of the way that some of this stuff has advice has changed over time um pxe was originally created for the mobile app use case because of limitations in in handling client secrets in mobile but because of those same limitations that also applies to javascript apps but it turns out that there are other attacks that weren't considered one pixy was created that pixi actually solves so again client secret pixie are totally different issues and the the answer is yes you should always be doing pixie and if you can use a secret you should always use a secret okay let's do one more uh one more topic here i want to introduce openid connect and we're going to see how easy it is to add it to the flow and i think we can do that in the time we have left so again opendd connect is not a whole new thing it's a small new thing it is a layer on top of oauth so we've already seen how oauth works we've gone through a flow we want we want to see now how do we actually learn about the user because what we've done is we've got an access token that access token will let us go talk to an api to fetch data but we don't know who the user is the application gets where's my access token the application has this access token here the only thing the app is going to do with this access token is go use it in api requests so openid connect is how we can actually go and learn about what's the user's name what's their email address the way we're going to do this is by introducing a new type of token called an id token this part is a little bit confusing because sometimes these look like access tokens because many systems use the same format for both however these are not the same kinds of tokens and you cannot mix them up or bad things will happen so in general tokens have an audience which is um who the token is meant to be read by or understood by so that's you know an audience is is watching something that's the audience of the token is who is supposed to be watching the token the audience of a access token is an api it's a resource server that's the that's the only party the only role in this uh that is supposed to be actually looking at them and understanding what they mean the audience of an id token is the application this means applications are never going to look at access tokens and it means that applications are never going to send id tokens to apis okay an id token is a json web token it's defined in the spec a json web token is a three part token containing a header payload and a signature inside the id token are what are called a bunch of claims these are things that talk about the user or about how they logged in or other things about the system how do we get one well we have to do a flow how are we going to do a flow in my opinion the easiest way to do that is to use the flow that we've already done the authorization code flow with pixi this has a couple of really super useful properties if you if you ask for a uh if you ask for a id token using the authorization code flow you're gonna get get it back at the same time as you get the access token and what you're doing is you're getting it back over the back channel and remember the properties i said about the back channel you already know where it's from you know that it's valid you know it hasn't been tampered with basically what that means is that you can forget that it's a json web token and just read the claims out of the middle so that's what we're going to do let's go and uh give this one a shot we're going to skip over to exercise 4 on the website so where is my here it is um this one down here i guess i'm not really numbered so i'm gonna drop that link in the chat what we're gonna do is we're gonna turn our previous work into openid connect request and it turns out it's actually very easy all we have to do is take this which we know is an oauth request and we only have to add a new scope open id and then you put a plus because that's a space in url characters if we add the openid scope let's see if this is going to let us work oh uh this is telling us to skip ahead a step let me um let me just visit this url without those scopes first we got a new code this looks the same nothing's changed we haven't written we haven't changed any code other than adding the scope if we exchange this now look what we got back it's kind of hard to read when it's all jumbled up we've got access token which ends here and now we have an id token this is what we this is what contains the data about the user now again specifically because we got this from the token endpoint i don't care that it's an id token i can just in fact take the middle part which is the base64 encoded json data and read that so i'm just going to copy only the middle part i'm going to go grab my base64 decoder and decode that and take a look at what's inside what's inside is this is the main one that we care about sub short for subject that's uh who logged in that's the id of the user login it's not necessarily a um human readable or a meaningful name it's meant to be the random string that um random string that identifies this user nothing else in here is really talking about the user uh necessarily there's um this one is interesting this one is how the user logged in saying they log in with a password and then this one is when the user last typed a password at the oauth server because again remember how like i've logged into this oauth server already now like an hour ago so uh this is saying that this id token was generated now but the user last typed in their password a while ago so if your app cares about that it could use that information um the restless we don't care about because we got this over the back channel now if you ever store an id token in a cookie and send it back like have your browser send it back to your app or if you're passing an id token from one up to or if you're accepting an idtl id token from the outside world in any way you do care that it's a json web token and you have to do signature validation you have to do all the validation of these claims um which can get really tricky and it can be very not obvious if you've missed a step because you can kind of just it looks like it works even if you haven't done all the validation that's why you hear a lot of people complain about json web tokens and why you hear that like json web tokens are bad um it's not that they're like inherently bad it's just easy to sort of misuse them or forget to do things um and that's also the reason i like doing the authorization code flow with pixi to get an id token because then you don't need to worry about the json web token part of this you just treat it as base 64 and code.json data and decode the middle part um okay so we've got the user id what about the user's name so let's go back to our request we have to add more scopes so remember how there were a whole bunch of scopes defined by default on the authorization server let's go ahead and add profile and email to the request if we do that where's my request so here's scope open id plus profile plus email we'll leave the developer day in there also uh check the link now it lets us through click login again this step doesn't change because it's just an authorization code and the app will exchange that for an id token and then we have to copy the whole thing into this tool and check the work and now we have to make it happy by extracting the claims and actually confirming them so let's go paste that here to extract the claims but again this is just basically for decoding this data you can do that however you want um so oh that's the wrong one i want to paste just the id token there we go here's the subject what is the email address here it is and the name copy that here we'll go ahead and verify and we are done so i kind of skipped through the instructions oh i should probably show you that link um here it is so here's the actual lab text uh that's the link to what we just did so if you want to step through it again in the remaining time um [Music] basically all we're doing is we're taking the first thing we did in the first exercise adding in the scopes and then following the instructions on the openid exercise um cool so are there any other questions before we wrap up what do you want to do if you want to access two different apis two different audiences don't need two different access tokens um there's a bunch of different ways a bunch of different options you have so um if you first of all your apis could use the same audience the audience is is meant to represent which api is being accessed depending on whether those two different apis are like part of the same system you could separate out access to them by scopes instead of by audience if they really are like two completely different systems like made by different departments or then the uh then you may want to use different audiences for it um octa does not let you add multiple audiences in a single os server it's basically one authorization server to one audience so you would go to your authorization server list and add a new one and give it a new audience i think auth0 lets you do multiple audiences on the same authorization server so different different use cases there um so then in that case you could um oh and uh yeah we're getting some answers in the chat as well the again depending on the oauth server so octa not zero handles differently as well as other products handle it differently sometimes you can request a token with multiple audiences sometimes the server will let you only request a token or you don't even get it request the audience claim it just will appear but the other way to handle this is using scopes and we'll get more into that in the afternoon session at the end of the day when i come back and we talk about apis and we'll talk about designing scopes for those apis um which is where that comes into play more uh matthew asks fat or thin id tokens when do you get each and why another good question so um let's see what we've looked at here is we've got some information in the id token right these are the claims in the token now what this means is that um the oauth client asked for the uh did in fact ask for the scope name and pro profile and email and it got back this information in the token some servers will not put it in the id token and instead you would have to use the access token to request this information from an end point this is basically the um idea of that this is the fat versus then token difference but um anytime that you're like bundling this information up into a token you've essentially created a cache it is a cache so this is a statement about this user record valid at this time which means if i go change my name on my account then this token can't hasn't changed right so if this is this gets it's very specific into how you're using these things but if you are um for example putting this in this kind of information into access tokens um or if you're putting it into id tokens and then using id tokens as your session identifier or putting it into a cookie and bringing it back to your app every time and reading it from there you're reading a cache so if you're if you're ever looking at the id token other than at the time it was created you're looking at potentially stale data so if you want to know about the most up-to-date version of that information in the token that's when you would want to go to the thin token model or just ignore stuff in the token and look up the information at the oauth server there are trade-offs to both uh because obviously it's never a good idea to just do one or the other but that's kind of the difference think of just think of when you've got this json web token that is a cache of data that was created at the time the token was created the system the state in the system may have changed since then and you won't really know until until you make a mistake by read by by acting on stale data so i feel like it's more of a concern with access tokens but that's for this afternoon's discussion a great question okay um fantastic so if you are watching this recap there should be links to all the resources down below as well so hopefully you can find the links to the exercises and the tools i used otherwise thanks all for joining this has been a lot of fun and uh we will go ahead and uh wrap this up here and come back and um in in a half hour we'll come back and have the next session which will be the off to zero session so thanks a bunch um i will see you all uh shortly see you back in a half hour um and make sure you've got your off zero account set up if you're gonna join that session thanks
Info
Channel: OktaDev
Views: 1,886
Rating: undefined out of 5
Keywords:
Id: Udrrz00PD3k
Channel Id: undefined
Length: 84min 24sec (5064 seconds)
Published: Thu Aug 26 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.