Spring Security Patterns

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay welcome back to the beginner friendly track here at spring one day two hope everyone's doing super great out there and uh enjoying all this incredible material a reminder that this is all recorded so in a few days we'll have it all posted up so if there's anything you missed please check back and and check out all the great content we have here at spring one and speaking of great content we're about to go into our next presentation spring security patterns with ria stein and josh cummings really excited to hear about this so without further ado here comes ria and josh hey everybody thank you for joining us it's a great pleasure to be with you today to talk about spring security it's always a good day when we talk about security right my name is josh cummings i'm on the spring security team as a maintainer i've been doing that for about three years which is great because that means i've been able to fool everybody for three years that like to give me this privilege of being on this excellent team it's an absolute delight to be focusing on application security and being with such passionate engineers every day and working with such a passionate and educated and supportive community so thank you very much for coming um i will let ria introduce herself and then we'll get going hi everyone i'm maria i'm also a maintainer on the spring security project i've been on the team for about a year and a half we're very excited to have you with us here today we're going to be talking about spring security patterns and not only are we going to be covering the patterns of spring security we're going to be talking about how you can apply them within your applications and we're also going to be starting off with an unsecure app and uh slowly making it more secure as we show you these patterns so i'll hand it over to josh and he'll get us started great thank you very much ria so as we had said let's get going taking a look at this application it's a simple spring boot application but at this point it's not secured and let me show you what that means if i hit the index endpoint of this application you can see that it gives me the answer it's a simple hello world app but it doesn't have any security it doesn't know who made the request and it doesn't really know whether they're authorized to make this request also in addition and this is a little more subtle there are no defense mechanisms inside of this request to ensure that the appropriate secure headers are as are are indicated as part of the response and those are things that we would like to fix we can fix that by um taking a look at our um our pom file we can go ahead and add the spring security dependency because spring security ships with a spring boot dependency [Music] um we can add it following the standard spring boost starter naming convention and say we'd like spring boot starter security and if you're familiar with spring boot what you know is that spring boot will collaborate with other spring modules in order to prepare reasonable defaults for for that module and that's precisely what this does as well if i restart the application then what i'd like you to take a look at is what kind of differences you observe we won't have time to go over all of them today but i'll show you a couple of them that teach a powerful principle about how we ought to consider writing our own applications frameworks and libraries so now if i hit that end point you can see that it behaves a little bit differently i don't get the whole low anymore in fact i get an error message and i get a status code that says 401 401 is the http status code that means you need to provide some authentication the authentication that we're expecting here is http or is is http basic the other thing that you'll notice that is that um along these same lines is that it doesn't matter whether it's an endpoint that you generated or an endpoint that boot generated if i hit a boot generated and point like slash error it also requires the same level of authentication by default this is a nice simple security posture to articulate spring security says by default every endpoint requires authentication that's a little more complicated than the ones that you created those require authentication but the ones that other people created those don't and so if you need them then you need to turn those on and turn the other ones off that can get more complicated than simply stating any endpoint that you would like to change the security on you can they are all secure by default there are other places where spring security by default demonstrates the same principle of being of having its defaults be secure for example if again we go back to this end point we can see that it's requiring authentication and you might say well what's the like what's the authentication i didn't see you josh provide any username or password in the configurations how am i supposed to log into an app by default i'm glad you asked if we go ahead and look for the default username and password for spring security which i'm sure you have never done this like you've never done this at 3am when you're trying to fix a production bug on tomcat like wait what was the default username and password for tomcat again i'm sure you've never done that only your friends have but if you do this with spring security you won't have any luck you'll see that there is a default user but there's no default password that's actually intentional that by default spring security when it starts up will give you a default randomly generated password for the default user let's see if that works we can go over into the logs find the password and then go back to the terminal and supply the user and the default and the default password and we work again which is great but why would spring security do that why would they make sure why would we make sure that the password is auto generated and there's no default password well it goes back to the same principle of secure by default in the event that you unintentionally deploy spring security with the defaults that application is not a liability now where there's some known searchable username and password that folks can find on the internet and try and penetrate your infrastructure because of that this is a principle that we can apply in general as well in your applications you can think about this same principle of being secure by default for example when you create an application in the beginning you probably connect it with something like an h2 in memory database because maybe there's no database yet for the application that you're building that's a perfectly sensible thing to do and it's sensible for you to place something like that in application up properties now when the application is mature enough to deploy you might create a prod application profile and change those to be the um change those to be the uh the production settings that you need for the database that's that's fine but consider the consider this risk that you have which is what if i forget to set the profile what if i accidentally deploy with the defaults then we might have the unfortunate consequence of being deployed with the developer's h2 database a more sensible way to do this is to have our defaults be the secure ones and our developer level ones be in a developer profile that way the developer settings don't accidentally get out to production when we think about the principle of secure by default we can find a lot of these circumstances where we want to ask ourselves if this accidentally got deployed without without setting the appropriate settings for that lane say what would what would happen to my application if it doesn't deploy great an undeployed application is a secure application if it doesn't um or if it uses the appropriate settings because those are the ones by default awesome that's great and that's secure um another principle that we want to draw out from these initial settings of spring security is the principle of least privilege it's another important and common security principle that we ought to consider following throughout our entire application if we take a look at a different endpoint say one that i've just invented that clearly doesn't exist you can ask yourself what ought to be the behavior should it return a 401 should we turn off 403 or 404 remember that 401 means i require authentication and 404 means that this endpoint doesn't exist well if you remember spring security's default security position which is that every endpoint requires authentication you can understand and expect that spring security would give a 401 here as well however there's another subtle thing going on which is the understanding that endpoints are privileged information you can imagine for example if i returned a 401 here where i said slash index.jsp if my app did that but returned a 404 here when i requested index.html instead of jsp if one endpoint exists and the other doesn't and i return a 41 or 404 accordingly now a bad actor an untrusted individual can know that the underlying technology is jsp because the jsp one returned to 401 whereas the html one didn't end points are privileged information and because of that we make sure to behave the same either way and we don't give that privileged information of whether or not the endpoint exists there are a lot of other places in your application where this kind of thing comes up one is if your application considers usernames to be privileged information is it okay for an untrusted user to be able to know whether or not a given username is a is a valid username in your system this is commonly considered to be privileged information which is why it's very common on username and password pages to say your username or your password is incorrect instead of stating which one and we see the same kind of thing and forgot your password if we consider usernames to be privileged then we don't want to just straight out tell an untrusted individual that that username is correct or incorrect instead we should say something that doesn't reveal that information and keeps it privileged like if that username exists then we've just sent an email to the to the email associated with that account the second approach is a better approach because it keeps that information privileged and the a bad actor can't use a signal based on how we um behave differently with valid and invalid information in order to derive information that maybe we didn't intend to disclose you can do the same kind of exercise with bank account numbers with people's addresses with any kind of information that you know the only trusted individuals should be able to see so what we've done here in the beginning is show some spring security defaults and how those defaults represent a couple of important security patterns that you should keep in mind with your application what ria is going to do now is she's going to start diving into the app and changing some of its behavior to demonstrate some architectural and design patterns that you have to be thinking about when designing your application and how spring security employs those thanks josh we just saw that spring security by default will give you a default username which is user and a randomly generated password and that's great we want our application to be secure by default when i'm creating my own application though i want to supply my own user store and the way to do that in spring security is to expose a user detail service bean so that's what we're going to do right now i'm going to create a new class and i'm going to call it security config and this is where all of the security configuration will go for the rest of our talk i'm going to annotate this class with at configuration and in here i'm going to provide my user detail service beam for this application we're going to have two users we can have one user with the username ria and the password password the roles user and we can have another user this one can be josh and this one can have the username josh and we'll just store our users in memory so we'll return an in-memory user details manager of course when you're building your own application you might want to connect your user detail service to a database or you might want to use something like jdbc but for the purpose of this demo we'll just keep our users in memory so now i'll go ahead and restart our application and we can use these new credentials that we've just created these new users to log into our application if i come to the terminal here let's try logging in with ria oops ah i forgot a parameter there we go and it says hello and if i scramble up the password and it's an invalid password then i'll get back a 401 unauthorized as you would expect and the way we were able to accomplish this was by exposing a user detail service being that spring security then picked up and used when it was validating the users and this is a pattern that you'll see a lot within almost all of the spring projects and that's component based configuration here we created a component specifically a user detail service component and that impacted our security configuration specifically spring security used bean injection to take this bean that we created and actually use this bean when validating the user so think about that for a minute it might be different than other styles of configuration that you've seen because here we're providing a component that the framework is actually using in the application this isn't just a component that specifies configuration we're not just setting some flags or setting some variables or some specific properties we're actually able to modify the component and that's pretty cool uh other than being cool though this is also very powerful for users of spring security because you are able to customize the entire user detail service you get full access to whatever customizations you need to make to it you're not depending on the framework to expose certain properties in order for you to configure them and the other thing that this gives you is it makes it very easy to come to a conclusion about what the security of your application is you can see here we have a user detail service and this when we provided our own user detail service it overrode the default one the one that was generating that user and randomly generated password so by looking at the components that we've configured we can very easily see what the security configuration of our application is again it goes back to a security posture that's easy to articulate we're not wondering whether by creating this user detail service we're combining it with another user detail service we're actually supplying the component that the framework is going to use to validate the users so we've been talking about the framework using the service to validate the users but how is it actually doing that and where and the answer to that is in our logs in the new 5.4 version of spring security that's coming out next week we did some restructuring in our logs and the goal of that restructure was to make it very clear how spring security or when spring security is intercepting your request and what it's doing along the way so let's go see that i'm going to first change the logging level to trace so we can get some more information and then restart the application and then i'll come back to the terminal and we can make another request this time with the valid credentials so let's come back to our logs here if we scroll up we'll see that one of the first places that spring security is intercepting this request is in the filter chain proxy and that's the entry point where our request comes into spring security here it's saying it's trying to validate the request against the default security filter chain and it's using the request matcher any request and we talked about that before by default all of the requests are going to be secured therefore any request needs to come into the filter chain after that we have a list of filters which will each be applied to the request one by one in the order that you see them here so if we keep scrolling down we'll seeing the filters being invoked that's the purple we see invoking web basic manager integration filter invoking header writer filter invoking username password authentication filter and so on at some point we see we get to the basic authentication filter where it's going to authenticate our request and after it authenticates our user it's going to set this username password authentication token in the security context folder now i'm not going to get into what the security context folder is right now we'll touch on it a little bit later but i want you to see the information that's stored in this username password authentication token we can see the username is ria and we can see that the authorities are a role user and i was able to get that information from our user detail service and then if we open one of the filters so let's open the csr filter we'll able we'll be able to see in here the pattern that's at use there we go and any of these filters that you look at will implement the filter class this one specifically extends the ones per request filter which in turn implements the filter interface is what i meant to say and each of these filters will also have a do filter or do filter internal method which is what we see here and within this method they can either they can choose to process the request or not and then they can either call the next filter in line on the filter chain or they can choose to terminate the filter chain here so if you're familiar with the chain of responsibility design pattern you might have recognized that that's what we're using here the it's a little bit different there are a couple of differences between our filter chain and the chain of responsibility design pattern if you're trying to make a mapping our filters here are what the design pattern calls handlers or processors so you can use that as a mental map if you're familiar with that design pattern and this is very useful in the context of the security filter chain because for one we can easily add or remove filters if we decide that there needs to be a new filter when the request comes in we're able to add that filter without disrupting the filter chain because each one has a single responsibility and doesn't rely on the other filters for its own processing but even more importantly from a security perspective is what i had mentioned earlier that a filter can choose to terminate the filter chain after it's done its processing so for example here let's look at this cser filter this filter is protecting our application from cross-site request forgery attacks and what the way it's doing that is it's checking if a request has a c surf token and if that c surf token matches the expected c serve token and if it doesn't uh right here nope sorry a little bit further right here we can see that it is able to return without calling the next filter in the filter chain and from a security perspective for one thing that's efficient we don't need to call the filters um in the rest of the chain because we already know that this is an untrusted request you filters that might be validating the username or doing something more involved that might give the user some more information once we get here and we know that this request is untrusted we're able to exit the filter chain without proceeding on to the other filters like the basic authentication filter all right that's enough about this easter filter remember how i was talking about that security context holder and how that's going to come into play later well josh is going to show how we can use that security context holder in our controller to get some more information about the logged in user [Music] great thank you via let's take a look if i open up our controller that has that index endpoint that you already caught a glimpse of it's uh it doesn't do anything more than just say hello now that we have authentication and we have the assurity that spring security is protecting each one of the endpoints we want to see if we can take advantage of that information to personalize the experience for the user uh generally speaking most applications are multi-user applications and we want to be able to look up those users preferences or we want to show their last set of orders or whatever it might be it depends on who the user is and we need to be able to know who that is to pull out the right information and so the way that spring security provides to do that is what's called the security context holder we can call the security context holder and get the currently authenticated user [Music] i'll talk for in a minute about how that's done if you're familiar with java and how state works in java it might raise an eyebrow wondering how it could possibly be thread safe for the currently logged in user to be inside of a static class that is calling clearly a static method and i'll talk about the design pattern that's followed there to make that possible but first let's go ahead and add the um add add the user's name to our application so it gets a little bit more personalized so instead what we'll see is it will show um hello josh or helloria accordingly so let's go ahead and give that a shot if i go and hit the endpoint with ria and password then now it says hello rhea instead of just saying hello and if i say hello josh then it also says hello josh great we have a more personalized application what's nice about this particular part of spring security is that we can get the logged in user from anywhere inside of our application the user as well as other kinds of things in other common kinds of cross-cutting concerns in an application is something that maybe we don't want to perpetuate through our entire api in in our own personal application a case in point is in a previous life um i was rewriting and restructuring the logs in in an application that i supported and we wanted to have the username inside of the logs well because spring security exposes this via this static class i was able to inside of our log preparer that was that was adding pertinent information to to the logs add the user without having to percolate that user all the way through the contract down to where things were being logged a very convenient thing to be able to do and there are lots of other use cases where we need to be able to get a logged in user just right away when you know wherever wherever we are in the application how does spring security make that work and under what circumstances might it be helpful to do that same kind of thing in your application so spring security uses what's called the request thread local pattern and what happens is and there is i'm doing a little hand waving to make it look make it fit on the slide other repositories and when it finds the security context the previously logged in user for example then it sets it calls this set context method and then proceeds with the rest of the filter chain that we had talked about where does it store this context though it stores it in a thread local variable thread locals are a powerful concept inside of java that allows you to store data that is isolated to a given thread so no other thread can see it this is nice and servlet applications which spring security's spring security is mainly built for or initially built for we support reactive applications now as well but in the cont in the context of servlet based applications uh a single a thread excuse me a request is served by a single thread and so because of that because all of this is at the request level and is on a per request basis we can safely store something in a thread local variable and successfully decouple that request level information from the http request itself for example like i said earlier we can go call it inside of any method that we want that is clearly not directly tied to the two servlets or to the http request at the end of that servlet it will go ahead and clean up the security context holder and that's because if you recall a single request is served by a single thread but that thread comes from a thread pool and that thread might be called on for the next request and so we want to make sure to clean up after ourselves so the next request doesn't get any information bleed from from earlier requests that we're also using that same thread local instance as a note if you're using reactive applications it's a little bit more it's a little bit different um because thread locals don't work super well with uh reactive applications uh at this point uh so the recommendation uh the the recommendation is that you use reactor's context object to do the same kind of thing if you have a need to take something from the request and decouple it from the request to make it available throughout the rest of your application the request said local pattern or using reactor context is a way that you can do this other applications are are using for example log4j's mdc which also uses a local variable to store information that log4j needs in order to be able to log special information that that maybe you gather from the request but don't want to percolate through your entire application so that's great it's a nice and handy pattern but we can do a little bit better than that inside of a controller ria earlier mentioned injection and we would be remiss if we were at a spring one conference talking about design patterns and we didn't mention dependency injection uh and happily there's a nice application for it right here which is method method our method parameter injection in mvc controllers like like this one um you can tell spring to please go get the current authentication from the security contacts holder and just provide it to you in your method call this is a powerful idea because um now we don't have to go and don't go and get the value the principle of dependency injection or inversion of control is to have somebody else give you the thing instead of you having to go and get it and that's that's the principle that we're following here let's just check to make sure that it still works and it does and then i'd like to show you something that uh because we're thinking about dependency injection we can be even more powerful than this and spring security has some annotations that you can use in order to further simplify the parameter type itself for example i can use the current security context annotation to say um when you call this method please take from the security context holder call from security contacts call the get authentication method and then from there call the get name method what you just saw earlier and take the result of that and coerce it into this type inside this method so again it's using the notion of method injection and it simplifies the contract the reason we might do something like this is because it makes this a little bit more testable it makes it a little bit more decoupled from string security and the outlying framework that's helping make this application happen because this contract only takes a string and returns a string now in order to test this business logic all i have to do is provide the string and that's a lot simpler of a unit testing use case for us to consider we were able to do that because we inverted how we were getting the logged in user by going and getting it from the method so a couple more patterns that we've been able to see we've got we've got a slightly more sophisticated application what we'd like to do now is we'd like to transition the authentication mechanism we want to show you how simple it is in spring security to change say from http basic to a resource server and the reason that we want to do that is twofold first like to demonstrate the consistency in the api but also really http basic is these days limited in the ways that it can be applied it's a nice way for us to begin in a demonstration because it's it's a simple conceptually to begin with however in a real application there are certain security recommendations that aren't as compatible with http basic these days for example a password ought to be hashed and that password hash function ought to take half a second or a full second in order to defend or mitigate against brute force password attacks well if you have a rest api that is that is performing that sophisticated hash on every request which is what http basic requires uh then your performance is going to go down and you won't be able to have the resilient application that that that you might like and so for that reason ria we're going to move back over riya is going to share a couple of a couple more important design principles for you to consider one being immutability and another being composition and uh she'll show that in the in the context of how spring security uses those uh while at the same time changing us over to using a resource server thanks josh and yeah that's true i remember when i used to be a consultant i built quite a few resource servers but i can't say that i built that many applications that were secured by http basic so let's turn this application into a resource server the first step is to add the resource server dependency and that's just spring boot starter oauth 2 resource server next up we're going to come to our security config that we created earlier and we're going to get rid of this user detail service because a resource server depends on the authorization server to make authorization decisions so we'll get rid of that and then finally since we are depending on the authorization server we're going to need to tell our resource server where our authorization server is so let's do that here we're telling our resource server that our authorization server is running locally on port 9000 so let's restart this application and while this is restarting i want to quickly head over to our authorization server that we have here and you might have noticed already that this is a spring boot application and this is possible because of the new spring authorization server project that we've been working on for the past couple of months and when i say we i don't just mean the spring security team i mean the spring security community this has been a community driven project where we've gotten a lot of great contributions from the community so thank you to everyone that's contributed and if you're interested in contributing you can check it out in the spring projects experimental github repository and it's called spring authorization server we recently released the 0.0.1 version and this is how you can add the dependency to your project if you want to test it out again it's in spring framework security experimental and it's called the spring security auth 2 authorization server here in the dependency so let's come to our clients that are configured within the authorization server we have a three we have three clients and the first one is our pilot client the second one is our passenger client and the third one is a sailor client and i want you to take a quick look at the scopes here our pilot client has aircraft fly and aircraft board escopes our passenger client has aircraft board and our sailor client has boat sail and boat board and these scopes will come into play a little bit later all right by now our resource server should have started let's come back over here it looks good and let's come over to the terminal and make a request first we're going to need to get a token from the authorization server we have a little script to do that i'll just show you the script all it does is it makes a curl request to the authorization server token endpoint and it's supplies it with the client id and secret so let's use this script let's get a token for our pilot client and let's make sure that this token is here awesome so now we can use this token to call our same application as we had before which is now a resource server this time we're going to supply a header the authorization header and we're going to send in the bearer token that we just got from the authorization server and look at that it says hello pilot client um if we look at our application and our controller you'll notice that it's the same um dependency injection that we were using before where we're getting the name from the authentication object and that's why it's able to say hello pilot client if i were to try it with a different client it would say hello passenger client or whatever else that the client's name would be um so that's that's fun we were able to keep the functionality the same while turning our application into a resource server but since we have this fun travel themed authorization server i think we can make our resource server this application here a little bit more interesting and we've already set up a location service here which is injected using dependency injection into our controller as we saw previously and it has a single method called move to and this method will check first if you have the authority captain and if you are a captain then it'll let you change the location and it'll tell you you have moved to whatever the location you supply if you don't have the authority captain then you'll get an access denied exception and you'll not be able to move now some of you my head might have already spotted a problem here um having to do specifically with the captain authority and if you haven't spotted it yet let's go take a look at the logs and you might be able to spot it there we when we look at our authentication object here this is a jot authentication token we can see the granted authorities that exist in the authentication object and right here the authorities are scope aircraft fly and scope aircraft board and those scopes or these authorities came from the scopes that were supplied to the client in our authorization server and the default mechanism that spring uses or spring security uses to create the granted authorities in a resource server is to map the scopes that come in from the token to these strings scope underscore whatever the scope name is so from the way spring security works by default we're never going to have the authority captain so let's try and fix that one thing that we might try initially is to manually add that authority since we're able to get the authentication object and get the list of authorities maybe we'll just try and add that authority ourselves first thing we're going to do is create a new endpoint where we will allow the user to change the location this is a post-mapping to location where you supply a location string and then it just calls the location service move to and we also are injecting the authentication again so since we have the authentication something we could try is to get the authorities and then add the additional authority that we need the captain authority so let's try that and we can already see it's not compiling and that's because the uh list of authorities is actually an unmodifiable list so you can't add something new to it you also can't set the authorities or set the name of the authentication and that's because spring security doesn't want you to spring security is managing this authentication object and it's made it essentially immutable other than a couple actually one thing that you can set because it's setting the authorities and it's setting the authorization it's making the authorization decisions at authentication time and after that it doesn't want you to come and modify it of course we could you know we could get around that we could copy over the authentication object create a new one and do some hacky stuff there but when the framework is trying to tell you not to modify an object you probably shouldn't be modifying it and so you can think about that in your own applications too if you think about immutability you should think about which of your objects should be immutable and also which of the fields in your classes should be set if a user shouldn't be setting a certain field then maybe you shouldn't have a setter for it and you should consciously be making those decisions about whether you want a user to have certain abilities to set things or change things all right so spring security doesn't like this what we can do instead is what we did earlier we can use component based configuration and we can create a new component and then tell spring security to use it when it's authenticating the user so let's come back to our security config here and the authentic the component that we're going to create is a jot authentication converter and this does what the name suggests it converts the jot the token that comes in into an authentication object and specifically what we want to modify is the way that it converts the jot into a list of granted authorities so here we're supplying a custom granted authorities converter now um one other thing to think about when we were back at this application when we were about to set the custom authority was we were about to give anyone that has access to the location endpoint the ability to change the location and i mean there's nothing that said we couldn't do that but if we think about our clients the types of clients that we have maybe we shouldn't be letting certain clients for example our passenger client that only has the scope aircraft board to be modifying the location if you were on a flight you wouldn't want every passenger to be able to choose the location so we're going to use that same logic and only allow our clients that have the scope aircraft fly or boat sail to change the location and that's exactly what we want to tell spring to do in the jot authentication converter here what we want though isn't that different from what spring security is doing by default because by default it's creating those the authorities based on the scopes and we still want that because we might use that at some point in the future so what i might consider doing here is rather than re-implementing this whole convert method myself i could just extend an existing implementation the job granted authorities converter and this is the default implementation that spring security is using now again our code isn't compiling and that's because the jot granted authorities converter is a final class and again this is a pattern that's very common within spring security and it's because we favor composition over inheritance and what does that mean well extending this object would be inheritance but what we would prefer you to do is have an instance of this object have your own granted authorities converter in here and then you can delegate to it only when you actually need to i tried to do a shortcut there and it didn't work out for me um there we go all right um so now that we have this draft granted authorities converter in our convert method because we want to do something very similar we can use the existing converter and call convert here and once we have that result then we can do whatever we need to do with it so before i go any further let's talk about why spring security prefers or favors composition over inheritance well let's look at this code here for one if i wanted to use multiple of these converters if i wanted to delegate the two of them and then do something with a result that i get back from each of them i can have two of these converters and they can be different types here and i can delegate to each of them when i need to i wouldn't be able to extend both of these classes furthermore i am easily able to swap this out for some other converter if in the future there's a converter that suits my needs better that's already implemented i can swap this out and bring in a new class without impacting the api of the custom jot granted authorities converter one more thing is that i'm not tied to whatever public methods this job granted authorities converter might have i only really care about reusing the code in this convert method here i don't really care about any of the other public methods and i certainly don't want to have whatever public methods this other converter might have because all i care about is writing a convert method and then a final point i want to make about composition over inheritance is that it might change the way you're thinking about architecting your applications so when you're using composition you're able to use these components that you're delegating to or composing your your class out of you can use them as building blocks and slowly construct your class taking what you need from each of them a place where this is done very well is actually front-end uh frameworks like javascript frameworks um so if we look here this is some pseudo code for a front-end framework and in this example we have a registration button that we want to appear on multiple pages so we're prompting our users to register on multiple pages if we're if we want to reuse this code from the registration we're not going to extend the registration and then add or remove code from it but rather we're going to compose our new page out of various components that we might want to appear on the page so here were reusing the registration and whatever other components we might need and we can bring that theory over to our spring applications as well and use that thought process when we're building up our classes all right that's that's enough theoretical stuff for now um i have the granted authorities here and there's just one more thing to do and that is to add the additional captain authority if the client either has the scope aircraft fly or the scope boat sale so we have this let's restart our application and see if we can change the location all right let's come here we already have a token for our pilot client so let's make the request let's go somewhere let's go to seattle because that's where spring one was originally planned to be so let's pretend we're going there and then we'll pass seattle into our location endpoint and we'll still pass in our authorization header and we see we have moved to seattle great let's uh let's get a token for our passenger client and make sure that they're not able to access the location endpoint same request and this time we get back a 403 forbidden and it's telling us that we have insufficient scope all right so so far we talked about immutability and we talked about favoring composition over inheritance and using those principles we were able to clean up our application a little bit and make less work less work for us and delegate more work to the framework so josh is going to take that one step forward do a little bit more clean up on the application and show one more pattern great thank you ria um let me just do a quick time check to make sure that uh so i know how how much time we have left great awesome uh looks like we have plenty of time to go over this final pattern um let's take a look at this location service the location service is something that you and i are pretending is something that we're trying to interface with inside of our application and you notice it's doing something that maybe it looks normal at first but starts to feel funny as you think a little bit more about the long-term effects of one of the decisions that this method is made which is that it's performing its own authorization it's making its own authorization decisions in a large application where you have many methods and many services this would quickly become untenable because really security is not part of our business logic it's an aspect of each one of the requests and each an aspect of each one of our method indications on occasion programmatic security can be helpful but to put it inside this method as well as every other method would um would be a much more difficult thing for us to audit from a security perspective and to have a to have a fundamental understanding of how secure application is and is every method doing this appropriately there are two places where you can see this the first place excuse me sorry about that um the first place is here where it's getting the authentication from the security contacts holder pulling out the authorities and then asking if that authority contains captain it's deciding whether or not someone may call this method may make this request and if not then now has to do something else it has to decide how to handle the circumstance when there's when there's no authority so the last pattern that we'd like to demonstrate to you is called declarative security and it's another one of the fundamental principles of spring security we can use um spring security to remove the business logic here from the method for example there is a method called or there is an annotation called pre-authorized that spring security ships with that says in order to call this method you must have the captain authority so nice it gets rid of some boilerplate this looks a lot cleaner easier to read i want you to notice though that it's easier to have confidence that this is being secured correctly because all we need to provide in this case is an annotation as opposed to several lines of security logic that may or may not work correctly using declarative security means removing this security logic outside of your controllers and outside of your services and allowing spring security to make the security decision for you in order to make this work we need to make one other change and that is to turn on method based security which is not on by default and we'll say that we're using the pre and post authorized annotations this is one post authorizes another which i'm not demonstrating to you today and then if we restart the application we will hopefully see that it behaves just the same as it did before where it will allow pilot client to um to uh to change uh change let's see let's go and get a token first it will allow the client to change oh sorry it will allow the pilot to move the plane but if we try passenger client then it will disallow it pass and sure i hope that's how you spell passenger and we see that we get the 403 so it behaves as it did before and we get two benefits here we get a lot less boilerplate inside of our methods and we're declaring our security intentions to the framework this is easier for for all of us to look through our application reason about what the authorization rules are and have confidence that there's a framework handling the circumstances where uh making sure that those authorization rules are correctly upheld there's another way that you can do this too and the reason i want to show you both is so that you can consider the trade-offs that you would like to make in security as well as in any part of software design there are going to be trade-offs and there will be things that you can have that with one and things that you can have with another but perhaps not not not always both notice that we're making this authority check here at the service level and that's fine if that's what we want to do but we could make it earlier we could make it at the controller level if we can do it at for example the request level then we have another option the one aspect of spring security that we haven't had an opportunity to demonstrate to you yet is the dsl the dsl is a place where we can make centralized authorization and authentication decisions configuration decisions we can say i want you to be a resource server i want you to authorize this set of requests and you could also add here i want you to use http basic um here's how i want you to perform c surf protection something that that that ria alluded to earlier we can instead of putting it on each method we can go ahead and specify the endpoint here [Music] and say that we require that has the authority of captive in order to be able to call the slash location endpoint now notice this is request based instead of method based but also notice that it's all in one location if you use the dsl to declare all of your intentions then imagining a larger more complex application there's only one place in your application that you need to go to in order to see what kind of uh what all your authorization rules are if you use method based security while annotations are nice and and they're they're easy for all of us to reason about if you do use annotations one of the trade-offs is that you may get your authority rules being dis uh uh uh strewn throughout your application across each method but here you get them all in one place so if i go ahead and remove this now the location services is even simpler and all of my security configuration is now in just one location in my application let's see if it works we'll go ahead and restart and uh just try the same test again authentication tests are always are always riveting because all uh because what we get to show you is yes look it still logs you in or yes look it still doesn't log you in so let's see it still blocks the one user let's go ahead and get a pilot client and try that out and voila we're able to still move to seattle because we have the appropriate authorities so what have we learned well we went over excuse me we went over a number of different patterns with you today we talked about security patterns design patterns and architectural patterns that spring security uses in order to make the make spring security framework itself more secure and more extendable more usable for the community and we'd invite you to use these same principles inside of your own application they've they've proved useful to us over the years and we believe they will be the same for you so thank you for listening uh stay connected be secure you can check out uh spring security uh the project by going to the appropriate github link and then the following github link is the project where you can check it out and look at each step in the presentation that ria and i took and and see the code and play with it yourself so thank you very much for listening and uh well if you have questions please check out the slack and the zoom and we'll be there in just a couple minutes okay welcome back everyone thank you so much josh and ria that was wonderful if you have any more questions please go to our slack channel the beginner friendly channel over at the spring one slack and you can get the zoom link that will send you over to their q a they're gonna have their own special uh zoom q a in which they can answer any more of your questions again thank you so much ria thank you so much josh always great to see you and uh we have another presentation coming up at five minutes past the hour so we'll see you soon bye you
Info
Channel: SpringDeveloper
Views: 24,571
Rating: undefined out of 5
Keywords: Security, Modern Web
Id: xEnvAAhMGu4
Channel Id: undefined
Length: 54min 26sec (3266 seconds)
Published: Fri Sep 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.