Securing OAuth 2.0 Resources in Spring Security 5.0

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
my name is Joe grande yo this is Josh Cummings and we've been working on Olaf for those of you that that don't know I'm the new Ola support and resource server support the rich that we introduced in 5.1 it's just come out on Friday we started this whole Olaf journey the new OS support and spring security five back about a year and a half ago I started that up with Rob Lynch and really happy to have Josh on the team he's been working hard on the resource server side super excited about the resource servers for it and next we're gonna hit authorization server support but josh has been working really hard on this and this is we're introducing this and we get in this talk is all about really it's focused on a resource server but we are going to be showing some new client features as well and this is strictly a demo when those slides we're gonna basically demo the integration the unification of the OAuth client and the resource server within spring security I'm gonna give it to Josh so he could introduce himself for a bit before we start up sure hi my name's Josh and it's good to let's see maybe stand up here I don't know it's good to meet all of you it's exciting to be part of the spring team I joined back in February and it's been a real whirlwind great of a journey and it's been really exciting participating is something that I personally genuinely feel like the industry needs and it can can help a lot of folks it's a great it's a great place to be have long been passionate about application security and and I as Joe is I'm super excited to be able to demonstrate what we've been working on for well Joe for about the last year and half as you said and I for for the last six months so I hopefully you like it alright so we're gonna just dive into it the plan basically is we're gonna demo we're gonna provide it we're going to show you the end state of the application all right secured integrated with client and resource server and then we're gonna basically unsecure it and progress through showing the steps on how to enable a resource server and ultimately integrate the client with the resource server so let's uh let's jump into the demo I'll just quickly show you the application so I for those of you that are familiar with OAuth 2 log and I came out in 5.0 we got OAuth 2 log and set up here or it's actually open ID connect because we're using UA a as our authorization server that's an Open ID connect provider so so we log in here and it's just a basic messaging map right we could see our inbox as you can see I'm logged in over here Joe and here are my message is you know I could see my sent messages I could you know write a message to Josh right and I'll send this and there you go I could see it right I could look at it right you know the basic stuff I could delete a message and so forth right so pretty basic right but everything here the resource server is basically protecting the messages and and then we have the client application the architecture here is basically got you a a as the authorization server and and then we got the client application with the client integration and then we've got the resource server so 3 3 different applications now what we're going to do is we're gonna completely completely disable security or resource server security or basically no resource no protected resources right and we're gonna show you how that looks like and then we're going to basically progress through this sample enabling resource enabling the resource server and enabling the client integration so we're gonna start go back right from you know the beginning right now and I'm going to just demonstrate just prove out that we actually are not protected anymore log in here as you can see I could see all my messages right now or all the messages right I'm logged in as myself but I can see Josh's messages I could see Rob's messages and so forth and the sent you know all the messages so basically the resource server is just you know it's open right so now we're unprotected so let's jump I'm gonna hand this over to Josh right now and what we're gonna do in this step sequence is we're gonna basically enable the resource server minimal configuration absolutely minimal and simplistic configuration and then we're gonna progress with you know through more advanced configuration skull-faced authorization and so forth go for Josh awesome thanks Joe and thanks for that heartfelt message I really felt the the team to learn like the hey Josh hey what that was really really really thoughtful thank you so if you'll pardon me for a second there's a little bit of demo dust that I have to clear and that is because when we include the spring boot starter security dependency inside resource server is so good at just by default protecting the system that I actually had to kind of stomp on it a little bit in order to to get it to behave as badly as I wanted it to and it as insecure as it was when Joe saw it so I've removed that and then thanks for your patience with that here in the build you can see two dependencies that we've added in the resource server in order to in order to declare got the wrong one there we go good dill so you can see the dependencies here that I've added and there's two that are of particular importance this first one is one that you're probably already familiar with if you've had a chance to play with spring boot and spring security before you've seen this dependency this is the this is the entry dependency that you add into a spring good application to declare that you'd like it to be defended by spring security and simply by adding the this dependency we will spring security will defend every endpoint in your system whether it's a boot defined endpoint like slash error or something like that or it's a you defined endpoint via some kind of controller this we do both of these because it creates for you a nice simple to define security posture to begin from there are no surprises about what's secured and what isn't when we add this dependency spring security author resource servers some magic starts to happen this is the library that we need in order to declare that our that our application should be defended by Jah encoded bearer tokens when this is present and appropriately configured the application turns into a resource server and if an authorization header is present on a request and inside of it opposed the bearer scheme and has a job encoded bear token then these libraries wake up and parse the job and figure out whether or not that request is authorized there is one more piece that we need though in order to make it a fully fledged fully configured resource server and that is that we need to know where the authorization server is if you're familiar with let me just make that bigger for you if you're familiar with resource server authorization server and clients that is to say the entire Ola to eco system you'll recognize that resource servers in order to know whether or not a request is authorized it needs to inspect the bearer token and ask the authorization server some questions there are some different ways to implement this and what spring security 5.1 supports is jok tokens that have inside of them a jwk signature so for example what happens is if I go ahead and start this if I go ahead and start this restart this application we'll see it do a couple of things on startup what I've done specifically here is I've told resource server what authorization provide authentication provider I should point to by indicating what its issuer endpoint is and if I take that and bring it here into the browser so they think I have a little bookmark here then what it's going to do is it's going to take that endpoint recall what I paste it into the llamo and append the system will pin to that this URI it's a standards-based URI for discovering additional configuration information about the authorization server so there's a lot of detail here but what I want you to focus on is this line right here when we want to verify whether or not a job is legitimate whether or not it was truly signed by the authorization server and hasn't yet been modified since it was since it was created by the authorization server we need to have a public key that's one way to achieve this where are we going to get that public key well I could configure it directly on my resource server but that's problematic because well what happens when it needs to be rotated what happens when I decide that I want to invalidate that it's a little bit more of a difficult scenario to maintain a scale what we can do instead though is we can point to an endpoint like this this token keys endpoint it's a little simpler than maybe maybe reality but just because this is a dumb one we just have one key here with some identifiers right this is a standard endpoint that stood up by uua and other authentication providers where it lists some metadata about the public key some identifying information about the public key that is the pair to a private key that the authorization server is using to sign Joe tokens so all of that is coordinated initially by us inside our resource server declaring where should I go to get that metadata information right so all of this is taken care of for you because there's this extra effort on the part of spring' boot in conjunction with spring security all we need to do to get a minimal set up for a resource server is add those two dependencies until resource server the authorization server is so that it can find the Juke set the the jwk set cache it and then use it on future as requests come in so having restarted that let's go ahead and see the boring part of the demo which is that we'll go ahead and refresh this a on let's see hang on I didn't restart the server today we'll go ahead and restart at first now that we have it pointed to the issuer for for the OAuth 2 provider and what it's going to do is it's going to make sure that you have a resource that you have an authorization token in the header before giving any information so when we refresh this now it's kind of boring right we get an error and while this might cheese UI people a little bit it makes security people like me really excited because it's much better to give no information back than to give unsecured information right so this is a good step forward for us and then we'll go ahead and connect the client here in just a moment the resource server at this point will protect all endpoints both boot endpoints as well as you defined endpoints and require them to have a legitimate authorization token in order to in order to respond to them but o f2 is a lot more than just making sure that token is valid perhaps the reason that you're considering oauth2 is because of the inversion of control that it gives to the user the user can based on his level of trust of your application of the client that you're trying to use of the underlying system that is the steward of the data which pieces of information that user is ok with to trust you with that authority you've seen it before and Joe showed you when you when we log in we have some check boxes right and you've seen this before in facebook or Google or if you've used spring security 5 you've seen it there as well where you can say I'm ok with you having this data and this data and this data we're not doing any of that right now so let's add a couple of things then after that we'll turn it over to Joe to to put all the connections together so let's check out two spots where resource server gives us some some nice some nice muscle the first spot we're gonna look at is with queries now queries may not seem like anything particular with request with respect to authorization but they do write if you are in a multi-tenant environment or if you're in a multi-user environment which most of us are then we want to make sure our queries include the user in context so we don't return too much information the reason that in Joe's demo you saw everybody's information coming back is because we didn't have spring security in here and we weren't able to include the user in context inside of our queries so here if I go ahead and add a couple of where clauses let's see then you'll see that it looks very similar to other spring security you'll see that it looks very similar to other spring security queries that are enhanced by spring security data and I bring that point out particularly because one of our primary goals was spring screen 5.1 and folding in off to support two it is to hopefully make it feel very similar to other ways that you have at your disposal to secure your application whether you're using resource server or form login or HTTP basic or something else they all should feel very similar to each other the one place where this is obviously a little bit different is the principle is the trusted jot once we get to a point like this we've already decided that the jaw to secure that the signature is valid and what have you and we've deserialized all of the claims into a map that you can access any part of it in order to enhance your queries and so whether it's the username in UAA's case or using another auth provider that that uses excuse me that uses the sub field or something else we can access each one of the claims easily in each one of our queries and then we have we have another one here just to make the whole app work so I'll just add that really quickly and and then and then we're good to go so that's one of two places that I wanted to add some some firepower that comes from adding the resource server this one being changing the queries to include where clauses that that address specific claims inside the JA token another spot that we want to add this is let's go ahead and add a new class if you're familiar with spring boot you recognize that it will create a couple of beans for you and this is a common case oops looks like I have a little typo sorry in second spring boot what about due by default is if it doesn't see a web security configurator well create one for you and when resource server is included this is what it creates and since we're gonna customize this a little bit I'll go ahead and create my own web security configure it after and now spring boot is gonna back off it's not going to create the security adapter for me anymore and it'll allow me to configure how I want to so the second thing that I'll add the first was was the queries and then the second thing here that I'll add are a couple of endpoints I add these for a couple of reasons one of the primary reasons is because again I want to emphasize that this should look and feel similar to other spring security things that we have in the past specifically note here that we didn't want to call it a roll underscore but you see that the naming convention is very similar if you've used spring security in the past you know that rolls by default are prefixed with roll underscore these are prefixed with scope underscore part of that reason is a name spacing concern to ensure that we don't Trump accidentally other authorities they already have in place in your existing applications so it's a defense against accidental Mis configuration but also it gives you an idea of provenance right that these authorities came from a Jah token we can also configure this a little bit and we'll come back to this in a moment configuring your own granted authorities and customizing that a little bit the second reason though I want to include wanted to include both of these to re-emphasize this idea that resource servers when they are with excuse me when applications are participating in an auth flow and we want to protect them as a resource server we should take advantage of that we should make sure that we're meeting the user or the client at the level that they're comfortable with in relative to the trust that they have over the entire system as a whole so because I have these two separate endpoints and the two separate scopes I can give a slightly different experience in the application based on what the user is comfortable with sharing let's see so what we did is we added resource we excuse me what we added is we added two URI endpoints and we added and we added some query it's give me some somewhere clauses to our query that allow us to behave as better stewards of the data hopefully relative to the users preferences and I think that at this point Joe we're probably we probably are ready to connect the client let's definitely let's do that I'm just gonna set things up here to the point where we're at right now there was a couple other changes but just make sure we're in their correct state so yeah right now what so now so we got a protected resource server right using a you know scope based authorization so now we got to get the client in integrator right so obviously what does that take obviously we got past an access token to the resource server right so I'm gonna show you how that happens with with the five one features of oo auth clients now I can open up right now we have so the initial support for for the OAuth client support is with web client rest template support might come later but right now the initial support is with web clients so if you want to make a protected resource request with an OAuth client you're gonna be using web clients right now in the sample application we just have you know we've exposed the web client being with its default you know properties so what we got to do we got to configure it customize that web client being with with the necessary configuration with the OAuth client integration so let me kind of just go over this code here so so we have we have this servlet a lot to authorize client exchange filter function that is one long class a no doubts but let me explain it to you obviously this is this is a servlet based application right this is not a reactive based application there is a counterpart to that which is called server authorized client application and so forth and with web clients you got this functional interface to the exchange filter function which allows you to plug in to the whole request and response processing lifestyle lifecycle so this is how you know you implement you know pre proces post processing within a web clients so this this servlet OAuth 2 authorized exchange filter function does all this work and the features that it provides is from a high level is it will at the very least they'll add the access token to the authorization header if the authorize client doesn't exist it'll retrigger the authorization for the authorization code grant for the specific clients it'll also refresh your access token if it expired right so there's there's quite a bit of functionality in there but as far as configuration goes this is pretty much all you got to do instantiate this class pass in the client registration repository the authorize client service and then apply it to the web client builder applying that exchange filter function that does everything that one-liner right there that apply a lot to lawsuit configuration that's literally all you got to do right as far as the configuration goes now we still got a obviously pass that access token so we still got to get that other end of things going because right now the infrastructure components within the customized web client it's all set up that's all you got to do right now if we go to let's go to the the messaging controller and see what we got to do here to pass that access token and I'm just going to add this this one-liner here right here and I'm gonna explain this so well to authorize client we're passing in okay we're gonna backtrack here this this first annotation here this is my name of my sent box the inbox is the same it just delegates to this get messages but I want to talk about this registered a lot to authorize annotation so it's a handler method argument resolver that ultimately resolves an authorized client so an authorized client for those of you that are not familiar is so at the very beginning the client with OAuth to log in it triggered the authorization request right and then you got the consent screen you clicked on authorize or D authorized or deny or whatever and then you click the authorize write and you completed that authorization code grant flow the end result of that is you have a principle or the resource owner you have a client or the client registration in spring security terms and then you have the access token then the result of that so an authorized client is association of those three entities right this annotation as you can see here messaging that's the client registration ID if we look at the application yeah mol for the client for those of you familiar the client registration is set up like this right here we have the the messaging alright that's the client registration ID and all the other required parameters take a note of the scope there we got open ID profile you know on messages just take a note of that and I'm gonna you know get back to that but what this so what this reg this annotation does when you put it in one of your controller methods is if this messaging client was not authorized then it retrieves the authorization request right rhe triggers it you go through the authorization code dance and eventually when the access token is fetched by the client it comes back to this controller method and then it looks it up through the authorized client repository cuz that's where it's stored and now it's resolved right now we have this authorized client in here and as you can see we got a client registration and the access token and maybe a refresh token for the specific client depending if it's if it's been configured that way and if it is the authorization code grant flow so so that's you know how we resolve an authorized client now we have an accent we now have an object with an access token but you know I don't want to have to do any code I just want I just want it to work right and that's what this one line is here right this one line right here as you can see I just delegated this internal method get messages past the authorized client there and then I just called this attributes with the authorized clients now what is attributes now that's that's basically a request scope object right so with with web client you could set request scope attributes right that exchange filter functions could look up and do things with it and that's exactly what this does this sets a request go instance of authorized clients and when you know the infrastructure within the OAuth 2 integration it looks up this authorized client and the current request gets the access token sets the authorization header bearer access token so that's literally that's it like that's it for the client integration it's once again back to the decline configuration this does not change this is pretty much you know you're being you're done right and then the only other thing you just have to make sure you you pass the authorized client to the specific web the client request that year that you're using for that specific controller method so that's that's the integration there and now we're passing in token now let's see if this works now that we're passing a token I should be able to see messages so I'm going to restart this and we're gonna take a look at our demo and I should not be getting the 401 authorized anymore right and I don't and the good news is I'm only seeing my messages right now right this is only to me right I go to my sent messages here and there right from from Joe grant right so everything's that's it so at this very point we have completely integrated in enabled scope based authorization on the resource server and we've integrated the client to do protected resource calls with the server that's where we're at right now we're gonna dig deeper into a little bit of customizations right now when he try to send the message so I get this 401 unauthorized as a matter of fact what I was expecting there was four three and I'm going to proceed to to some of these commits because there was actually some other bits of code that I needed to add into this controller that I didn't really want to be sitting up here and doing that but basically the composed method wasn't passing the access token and therefore that's why I was getting a 401 but I just kind of rolled over to the next commit now it's passing it I'm gonna go back here just make sure everything's working okay now I'm gonna hit compose now I got a 403 all right that's because that's what I wanted because what's happening here is you saw the application damn well the client registration had the messaging scope but we also have this other scope contacts right and that scope allows the client application to get the contacts of the current user so I could in the drop-down I could see the contacts I could send to and plus there's there's some other there's some other authorization that happens with that skull so let's let's dive into that and see how we could how we could set up how we could set that up and this kind of leads me to customization of the authorization request users have been asking for this and and you know not surprised and and you know we can only get so much into 5.0 but 5.1 you could customize the authorization request you customize a token request you could customize the token response hand link for the authorization code that is for that and and for client credentials for the token request side of things but the authorization or class customization is obviously only authorization code so you could fully you have full control on customizing and adding custom parameters for example open ID connect open ID connect adds a few extension parameters for example II the prompt parameter right it could take in login or reconsent right so for example if I passed the prompt equals reconsent in my authorization request maybe that's what I want to do every time there's a flow that happens an authorization code flow that open ID connect that happens then it would actually I'm gonna backtrack that's probably not the best example prompt because that's for opening to connect but let's talk about if the prompt was reconsent right so I logged out of my application I've authorized it previously I logged out and then I'm using this custom parameter prompt reconsent next time I log in it's going to reconsent it's gonna ask me to reconsent again right so this is one of those use cases I'm not going to show that specific UK use case I'm going to show another use case but I want to show you how easy it is to customize authorization requests and ultimately add your own custom parameters so let's let's dig into that okay so I'm gonna add this so it's the authorization request resolver that's the core interface so I'm gonna add that here so ago we're gonna call a custom authorization request resolver okay and then we're gonna do this dump all that code in there let's take a look at this first off the core interface pretty easy right so authorization request resolver so it's got a couple of overloaded resolve methods the ultimate goal is return an authorization or through authorization request which will ultimately be used to redirect to the authorization server right the default implementation of this is the default authorization request resolver and it does what it does today with a lot to login and it does what it does today for for 5.14 the authorization code grant if in case I haven't mentioned it that's you know new and 5/1 along with the client credentials grant so it the default authorization request resolver it resolves it through this base URI oauth2 authorization in the client registration ID grabs all the data that's in the client registration creates the authorization request to the authorization server with your typical you know your your required parameter right so this pattern here if you want to tap into it or hook into it and add a custom parameter this is how I've implemented it right it's a delegation based pattern so my custom authorization request resolver in the constructor just initialized a default one because I want the exact same behavior and in the resolve here I just delegate its delegated to the default implementation it returns me an authorization request and now I have it now I could do something with it right and that's what's happening here in the custom authorization request method down here all I'm doing here is I'm basically you know getting the Scopes the current scope so that includes though you know the open ID profile email and messages and then I'm just adding the scopes the contact scopes in there right and then I'm passing into the from static builder method overriding the Scopes and then building and returning it so at this very point I've enhanced the authorization request with that extra school parameter and that's exactly what happens it gets redirected back to the authorization request now what you could you could do a lot of things here I could also completely override the authorization request because this authorization request has an attribute called authorization request URI fully qualified URI with the request parameters and everything that's ultimately what gets redirected to the authorization server if I wanted I could just you know use what's there and then append the parameter to it or just do whatever I want to it right that's one of the things you could do or you could you know there's also additional parameters map I could add you know custom parameters this is where I could add for example prompt equals reconsent add that in and and now ultimately get built into the authorization request so there's a lot of a lot of power here right now let's take a look you know let's take a look what happens here well first of all we got to configure right I've created this instance and now I got to configure it into into the security configuration so let's let's do that next and then I'm gonna add add the method here and then and then where we configure this is the authorization endpoint authorization request resolver that's it that's pretty much the configuration so obviously you got to create the implementation and then down here I'm just creating it right passing in the client registration repository but the main point here is I'm going to tap this it's more readable is on the authorization endpoint configuration that's where I define my authorization request resolver that's where I plug it in that's where I hook it in right so now that this is configured right let's give it a try let's see if I could you know access my contacts right now I'm gonna restart this up and we're gonna go back here make sure there we go compose there we go right so now I could see everything now I could see only that my contacts not myself included right so now we've proved out you know we got you know more finer grained authorization on the resource server it's I mean it's been established already now just I got an extra scope on my on my access token using that the the custom authorization request feature there now let's jump on to the next section that was some customization on the client there's actually quite a bit more customization that you can do but there's only so much I could show during this during this demo so what we're gonna dig into right now is some customization of the resource server alright so let's jump into that next with Josh thanks Jo and IRA can we give a hand to Joe for saying servlet authorized client exchange filter function why I was pretty tired that was impressive it took a lot of practice great but it's very very clear what we mean so that that's that's that's that's a win great so we at the very beginning of this this kind of journey to securing our resource server and connecting with a client there are a couple of things that we kind of passed by briefly that that we stated that we would revisit and I'm just going to point out what we're gonna look at again and kind of dig a little deeper into to see see what we can do to meet some more nuance to needs of of this resource server so the first is here you heard me reference that by default we prepend the scope the word scope to the front of each authority by default this has this has that this has the plus of defending against like namespace collisions and identifying provenance and what-have-you but it does have a slight downside and that is that well it has something that could potentially be interpreted as a lot too specific inside the name of the role and maybe I don't want that even more perhaps even more generally applicable is the the idea or the understanding that each of us has that granted authorities while the model is very simple the the procedure that each individual application might undergo in order to infer the appropriate granted authorities from some kind of job could be different from application to application and certainly from company to company maybe we want to look up granted authorities from a database or maybe we don't even have a scope attribute or an SCP attribute in our particular setup what am I going to do to establish my set of granite authorities easily because it doesn't really fit my specific use case I don't have a scope attribute it's not true that it's a one-to-one mapping between the scopes and my jaw to the to the granted authorities that I wanted my app so we'll do this little cosmetic change but keep in mind that that we're using the same API that you would use to perform more sophisticated changes on the set of granite authorities so let's go ahead and create a granted authorities extractor and there's an there's an extension point that you can see here called granted or skeeving called JWT authentication converter to understand the importance of this API and where it comes from we're going to take a look at JD Beatty authentication provider this class you're most likely already familiar with authentication providers in Springs security and this authentication provider is loosening this authentication provider is added automatically by spring but-- if we're using bring boots configuration and resource server as a dependency or by adding excuse me by calling these this sequence of methods in the DSL either way we'll get in our authentication manager a JA authentication provider which can look at a bare token and first of all decode it verify it validate the signature check the timestamps and do Mary do myriad other things on your behalf to ensure that the jot is trustable and then the second step is once we have a trusted JA to turn that into an authentication spring security authentication of course when we leave an authentication provider what we need to have is some kind of authentication object in order to be able to participate in the rest of the spring security API and so that's that that's the final goal of this authentication provider this two-step process allows you to step in depending on what you're trying to do are you trying to confirm the validity of the jawed or are you trying to take that JA in a set of claims and turn it into an authentication in our case we're creating granted authorities right which is part of the canonical spring security API right and so we definitely want to extend JA authentication converter I will say well let me let me mention one more thing here in just a minute well we'll get through this use case and then I want to point out one more thing about this converter that that's valuable okay so since I am connected to UAA and using that as my my olaf provider then i know already that uia uses an array to express its scope and it uses a property called scope so it's safe for me to be able to write this and oftentimes that'll be the case with with with your situations as well you'll know the way that the authorization server would like to communicate the authorities you need to pull them out in your own way and then perform your own business logic and since we know that it's a scope attribute and we know that it's an array we can go ahead and safely test it once I have this I can do something simple like map the authorities to to the simple granted authority object and each one again in my particular use case each scope does map to an individual Authority that I want resource server to be aware of but like I said earlier I don't want to have the scope prefix in the front right so that's my specific use case but of course this contract enables you to do quite a bit more depending on what level of sophistication you need in order to derive the authorities as an aside even more powerful than this if we take a look at this fellow right here at the end of the day he implements converter right if we need to do something still more complex and custom we can simply implement a spring security converter that takes it from a jot and turns it into an authentication and ensure job to do everything at that point whatever whatever jock comes back you'll generate your own your your own authentication in the end so let's add this we added on to the DSL and then at this point we need to make a couple of changes because we've now taken off the scope attribute or the schemee the the scope prefix right and so let's go ahead and remove those and there's a little Easter Egg here for you to check out afterwards which is inside here in message controller and this is a place where we're doing some fine-grained authorization you might wonder how we showed a name if we have the context scope but the user name if we don't right and that's that's right here and you can check that out if that's something that you're interested in but since we're also using that here well we'll remove the scope prefix from there too and this is kind of nice because if you take a look at this class which we don't really have a lot of time to review right now it's not a lot too specific there's nothing in here if you look through really about authentication at all other than trying to get the logged in or the user in context in order to perform appropriate queries and do-do-do our appropriate effort but there's nothing all wot centric about it so it's kind of nice that were able to remove that so there's there's no there's no implied a lot dependency in this class great with those changes I could do all the boring demos right because we're gonna refresh the page and we're gonna see that it's exactly the same as it was before but it's good to know that we didn't break anything so when I go over here we can see great nothing's broken we're stable too because we accepted the the token excuse me because we accepted the the Contacts authority we see the names because we accepted the messages authority we actually see all the messages as well the contact and message scopes awesome one other point that we skimmed over in the beginning I sort of mentioned it in passing was that they're ours there is more than one thing that this property does for us the first thing that we do that it does that we are all very grateful that it does is it does the discovery negotiation with an authorization server so it can discover the jukes endpoint and again it all set up so that you can be prepared in the future to do things like key rotation and other sophisticated things that you care about when you're deploying resource servers at scale it also because now spring security knows what the issuer is it also validates the issuer right so for example the in the claim set if ISS is in the claim set which it ought to be and if we've configured this then spring security security can automatically make sure that those match we can make sure that the from address if you will of the jot is the one that we expect let's let's dig into this just a little bit and we're going to add some more custom validation of the of the of the claim set what I need to do though in order to achieve that is a little bit of just a little bit of quick setup here we have this funny little UA a client that we have set up which is the expired client expired client comes in handy when you want your token to always be expired and that's going to come in handy here so there's our token it's kind of big and gangly so let's do just a little bit of massaging of that response so that it's more copy/paste able and now I can take this and here's a nifty tool if you haven't used it before I love this tool I mean it all the time John IO if we can if we can get it to respond if not that's okay I'll just tell you what's in the Top Gun oh great but this way you can see it and it's a little easier to to consider something that you can see instead of me just telling you what the values are I'll give it another second here what's inside if you've ever inspected a token before there are three parts to it the first part is the header the second part is the claim set and the third part is the signature and what we want to do is we want to be able to take the we want to be able to look at the claim set and verify that it's tents are what we would expect so for example you can see that this is decoded this it doesn't verify the signature because I haven't uploaded a public key to the website right but it can still tell me what its contents are for example here's the issuer this is the from address if you will of the job and spring security when you specify the issuer there and its configuration will automatically make sure that the from address for the jawed is correct the same notion the the the the converse notion is also in jobs and that is in the audience the audience is like the to field in a message it's Who am I intending to send this job to you'll see that by default you a a simply includes whoever was asking for it the client the client which is called expired asked for this job token so it's included in the list of audiences and there are other ways to configure and model audiences but for now this this simple setup is going to suffice for us and then the third thing here that you can notice here that's going to come into play with these with these validators that we're going to create and configure is that the job has already expired right because I created this sort of dummy client in UAA the each token that it creates only lasts for a single second and so it's convenient because now it'll already be expired let's confirm that okay well clear this up and then if I simply hit the resource server endpoint with the authorization header then we can see that we get so uni then we can see that we get an error here that the jaw is expired right okay so we know we're all set up correctly now what I'd like to do is I would like to confirm that the that the audience is correct so I'm going to create a very cleverly named class here called audience validator which is certainly not as clever as servlet Oh a to authorize client exchange filter function but but I worked very hard on it so and I'm new on the team eventually I'll be able to come up with longer names great so all this class is going to do is it's going to validate that the audience is what we expect it to be in this very simple situation all I care to know is that it is the name of the one client that I'm configured with and certainly we'll want to do we as we added more clients or more sophisticated roles or scopes this this nature the nature of this would change a bit but for now this suffices for us if it has the audience messaging then I'll be able to declare victory but if it doesn't then I need to hand back some kind of error hopefully some kind of informative error and so in here what I want to do is I'll want to pass an oauth2 error or a collection of errors it's a little hard to see but it's basically an all-too error or a collection of them and here's one that I can do bear token Eric stands a lot too error and it is it's it's a good thing for us to use if we're in the bearer token world like in a resource server this might not make so much sense depending on where you create this if you're not in a resource server that isn't say working with bearer tokens but the audience required is missing very very helpful message and then we'll simply add here to our response now I can use this interface to add any number of sophisticated validators I have access to the entire job all its claims and headers and I can I can validate a number of things you'll notice here in a mom that I can isolate them as well I can create a list of validators and compose them all together into a sophisticated validation strategy so that you can have each one focus on each individual thing that it cares about so let's do that here inside resource server config we're going to instead of modifying the way that we're our configure or turning the jaw into an authentication this time because we're dealing with validation and deciding whether or not we can trust this token we're at the we're on the other end of this authentication provider this time we're not going to create a Jonathan ocation converter instead we're going to create a dot decoder something that knows how to and wants to participate in the transfer of or the transformation of a string into a trusted job so let's go ahead and do that I've got this being here and Nimbus is our library of choice in spring security so this is this is the Nimbus implementation of a dot decoder and what we normally put this at the top but we'll put it here so you can see it all in one screen what I'm going to do is I'm going to change I'm gonna pivot from having a spring boot create this for me and look at this property and configure everything to me doing it so that we can kind of see what it's doing and it also allows me to add a validator my custom validator to the list so if we take this this issue or URI the one that's configured on our ml and we give it to this this helper class it's going to do the same kind of handshake that we saw in the beginning and create a decoder that has the appropriate and corresponding configurations on this you'll see that there's also excuse me you'll see also that there is a set validator method right which I can use to create any kind of sophisticated validation that I want that that is extended off of the defaults I'm in our case I do want to validate the job but I don't want to leave out the the default validations that that that spring security brings so I'll call Jacques validators to create default with issuer this is going to create the default validations the timestamp validator and the time step validator and the issuer validator I'll add to that the audience validator by using the delegating let's see the delegating off to token validator which simply takes a list right which validators do I want to use for my setup and we're done that's it by adding all so now by calling this method and doing this small amount of setup we will verify the timestamp will verify the issuer the the from and will verify the audience which is like the - okay cool so let's restart and go ahead and ask yourself for a moment what do you expect to come back here we know already that the token that we have that we created a little bit ago it's expired and we know that its audience is incorrect remember that it's audience is expired because that's the client that we use and the nights that we want is messaging so there's two problems with this job go ahead and think to yourself about what you'd expect when I call this now the response is that we still give the same and only one error message and the reason is because that may seem anticlimactic we're going to fix it in just a second the reason is because the bearer token specification spring security 5.1 and 5.0 have tried very hard to remain spec compliance so that so that you can proceed with confidence you can look at the spec see how it behaves and anticipate the spring security will behave in the same way and the bare token on specification is quiet on what do you do when there's more than one error and there are some off providers that do the the reasonable thing and they add something to the body to have all of the error messages others just give a very generic and unhelpful error message like there's something wrong with the jaw you're gonna have to go figure it out all of those are reasonable and they have different reasons that you might employ that and what what we did is just make sure that it's very easy for you to customize given your domain we go ahead and give back the first error message right and then then allow you to configure it as you need so let's add one more class and then and then we'll have everything we could ever want this one is going to be called the more informal informative authentication entry point and we'll base it off of the basic bare token entry point right the one that's writing that WWE authentication header because we like that we still want the www authenticate header we don't want to abandon the spec because there are folks that are probably integrating with our resource server and we need to make sure that they can go ahead and parse that just fine but in our case what we're going to do is well add just a little bit more information to the body which will give us the opportunity to let's let's put that on another line there we go which will allow us to have something a little bit more in the body so that we can see all of the different error messages and if the cause of the of the authentication exception was because validation failed then we want to take that validation exception and you know get the extra information out that that we were missing so let's just cast it real quick so it's a little easier to read on the line and then this exception it contains out more contextual information for you to be able to reason about the kind of error that you want to hand back it has inside of it we recall that on our single validator we could hand back a list of errors and since we have a composition of validators it's also true that we might have myriad errors coming back from all the validators together and so we want to go ahead and get those errors out and then simply render them like so now you might not use jackson and you might not want to put it in the body you might do 100 other different things but the point is here that I have a way to to do non-trivial type modifications to my error handling and what I say here is true for authentication entry points as well as access denied handlers right if you have an authentication error let's do the validation or something like that the validity of the jaw then then you can extend an authentication entry point if you have some special considerations you need to make at the authorization level then then you can do that with an access denied handle there just like you can with other kinds of authentication mechanisms in spring security so let's go ahead and restart luste last restart and then we'll hit the endpoint you always hope that there is no error at all on the very last restart but there you go because I forgot to wire it right so we'll just wire that then more informative authentication entry point to our DSL and by last restart I meant this is the last restart great now we'll go ahead and hit it one more time this is where Joe's wisdom comes in hang on we'll just because I can do this here right yeah Joe was very smart and said we should do this just in case so we'll go ahead and do that oh it was cuz I was restarting the wrong server haha okay great how's restarting a client instead of resource server I've done that a few times oh you've never done that you're perfect okay now let's try it oh okay good all right now if we let's go ahead and pipe this so we can read that a little bit better now we get more sophisticated representation of the errors right we see that oh yeah the dot has expired and the audience is bad right so I can go ahead and respond to both or debug both or what have you instead of having that awful like experience of well now I now - now it's not expired anymore shoot the audience of that - I wonder what else is gonna be wrong and you get each err one at a time and it's really really frustrating okay great so I know I've been talking for a long time quick review so we added custom token validation validating the claim set we added custom error handling and we added custom Authority mapping in this in this in this in this segment and I think that's pretty cool like the number of ways that that resource server can extend that we can extend resource server to handle our our domain specific needs so I hope you like it I hope you use it I'm gonna turn the time back over to Joe to do just a little bit more wrap-up and then I think we'll take your take your questions at that point right on thank you very much Josh those awesome there's a couple other commits in this repo that I want you know if you guys are gonna check it out we didn't have time to do it in this demo we you know during our dry run so good he's got to go out but they're in the repo and so for example if you want to be able to like handle you know 403 authorization exceptions or access denied actually exceptions are within Springs security on the resource server there's a commit in there where you could basically customize access tonight handler and do similar logic here you know just customize the response as well as on the client side mentioned earlier you could I've seen this a lot actually this has been reported a few times where you know provider doesn't comply us back for exam on the access token response the token type parameter is required in the spec but it doesn't actually come back with some providers I know LinkedIn is one of them and they can't get a while to log in working with LinkedIn well with five one you can write there's a commit in there that allows you to customize the rest template for the servlet side of things that handles the token exchange or the token request and response so you could ultimately implement your own response handler actually a sprint converter that converts the map to an oauth2 access token response think he's just default to token type bearer or do whatever you want really so those two commits are in there so I welcome you to check that out we do want to take some questions before that though and hopefully we have time for some questions if not we will be out there waiting for some questions tomorrow go check this talk out this is all about reactive spring security rob winch our buddy Rob Wednesday tomorrow 2:00 p.m. that's the room go check it out if you're interested in the reactive side of things with spring security and this here this is our this is a link to the demo the repo for the demo there's also two links there for oauth2 client sample and a resource server sample and we're gonna keep building this and building a lot of samples we're planning on doing like a much bigger reference architecture sample with microservices secure with OAuth and all the different grants and just you know proper you know best practices reference architecture it's going to be coming towards the end of this year rather than just one sample one advanced sample thank you very much thank you Josh we'd love to take some questions any questions everyone no okay great yes a lot to login yeah 5.0 actually we provided support for open ID Connect yeah I know what's called a lot to login the reason being is we have to like we have to make it work with standard OAuth 2 providers like github for example right it's not an open ID connect provider so we just kept that name a lot to login but that for if it's an open ID provider like UAE it does open ID Connect flow yeah so I probably should have repeated that question the question was the there's a lot to login support open ID Connect yes it does any other questions sorry the these are these slides online they're gonna be distributed with conference because we hand it in so yeah yeah any other questions go ahead [Music] well okay the question is do you have a way to handle the refresh refresh grants refreshing access token in a background thread well on the right sole on those you know this is definitely question for Rob because we definitely talked about that he's the one who actually implemented the web client integration and that refresh access token grant I'm not sure I'm trying to recall how he implemented but we definitely had that discussion so as far as synchronization issues go there should be no issues and if there is login issue and we'll fix it but you should be good but yeah Rob is definitely the guy to answer it but we had those discussions because we obviously first first saw that situation sorry I'm can use me yep [Music] so can I restate your question make sure I've understood you're asking the the public keys that are used to verify the the web tokens in 5.1 are those stored on the machine like caste or something like that is that your question yeah that's correct their caste and the way the mechanism works today is that whenever a Jacque comes in that the application does not recognize like the the metadata inside of it I can't be reconciled with the cache that it has using the the composite keys that it creates based on those header fields if it can't if you can't reconcile and find a key that matches that that metadata set then it will query again it will invalidate his cache requiere check one more time and if it still doesn't find it then it will say you know sorry this is invalid and I don't have a matching key so yeah but it's there it's it's there they're stored for you yep just to add to that for five two we are going to be adding revoked whole can feature it's a bit tricky with JW TS I mean those public keys are cached and we got we need a way to invalidate that cache but that's going to be coming in the next release any other questions sure sorry something other than John other than John okay so did you want to answer this way no God okay so four so also four five five points who we're targeting to implement the introspection endpoint soul pay tokens right we couldn't get into five one I really wanted to get into five one two but it's just so much work to do but five two for sure opaque token support the introspection endpoint specification we're going to implement that so so that'll be the next token format that will support were you asking for another specific format or were you looking for an opaque token support okay sure sorry authorization server that's coming also in in five in five - we got a lot of work everybody know it but yeah weird like this is we just introduced resource service for four five one but five two is definitely gonna be initial support for authorization server but that's a huge undertaking so it's gonna not going to be a full feature so we don't know yet exactly you we're still planning things out but that's definitely the plan we will be providing authorization server support including Open ID connect support on top of that right yeah right on thank you any other questions before we got to wrap up and we'll go we'll take one more question and then we'll go into in the back anyone else wants any questions answered go ahead can you speak up on just a little bit louder sorry [Music] good question so let me make sure to restate to make sure I understood so we initially provide bearer token support and your question is is there a way to for you to customize and do something other than a bearer token and still defend the resource server did I understand that correctly yeah good question so we're the the point at which you want to look I would say that we do not yet have well-defined support for it however it is easy to do and it's easy to switch out your authentication provider because that authentication provider is focused on bearer tokens right but if it's still a JA encoded token then you have the same libraries as you had before you have jock decoders authentication converters and you can easily invoke each one of those depending on whatever transport mechanism you have for for the JA and if it's not a job and something else then the the configuration point is still the same spot right still creating your own authentication convertor and you have access to all of the different API is there inside the resource or library we got a cut out here why don't you come out here just after yeah we got a cut out but we don't what we're gonna go out back there let's continue this for sure will answer your question thank you thank you everyone thanks everybody thanks for coming out you
Info
Channel: SpringDeveloper
Views: 42,671
Rating: 4.8954248 out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, oauth, oauth2, spring security, openidconnect
Id: 1N-xwmoN83w
Channel Id: undefined
Length: 71min 13sec (4273 seconds)
Published: Thu Oct 04 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.