Spring Security, demystified by Daniel Garnier Moiroux

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi everyone hey I'm Daniel um that's what I look like on the internet that's what I look like in real life kind of the same um before we start who here wanted to go and see venkat's talk and is stuck here with me instead first choice uh well it as we're speaking he has 566 hearts and I wanted to go see his talk but I'm stuck here with you so we're gonna have fun it's gonna be nice before we start my three-year-old is very curious at what I'm doing today so can you please make a funny face for him and one and a two and a three ah amazing he's gonna love you guys cool so I work for VMware in the tanzu spring group um so it's between the tanzu brand at VMware that does packaged products and the spring group that does the open source that you all know and love I also teach at a university in Paris in my spare time um python web and stuff like that you can find me on the internet and you can find me here after the talk during the break and we have a tanzu VMware has a a booth downstairs right in front of the cloak room and I'll be there during lunch so if you want to come and ask questions I'll be available for you so before we start on on Spring Security um who here uses spring and spring boot raise your hands cool yes that's that's a good start and who uses Spring Security cool and who thinks Spring Security is is really easy to use and easy to understand one hand one hand cool you can come and co-present with me um so that's why I'm here um I am going to to share what I've learned about spring security by contributing to it um Spring Security has a very it wants to be used in a certain way and when you go past the getting started guide that you find on the internet and you want to tweak it to your use case usually it's very complicated and so you go to stack Overflow and you copy and paste some stuff and it doesn't work and it's very frustrating that was my experience before I you know I dug in and tried to understand how it actually works and it's not that difficult it's it's complex as it has many things intertwined but once you have the basic concepts it's really easy to extend and make it do what you actually want so the the contents of what we're going to be talking about today first we're going to do a demo and the goal of the demo is not to show you the cool features of Spring Security and make you you know remember all the cool things that you do it's more we're going to do a Baseline and then from that demo we are going to be talking about uh theoretical Concepts or the architecture of Spring Security the patterns and we're going to extend on that demo so bear with me for that and then we're going to talk about you know the the the main concepts of Spring Security um so a few caveats before we start the the goal is not for me to infuse all the knowledge of Spring Security to you in three short hours um the goal is to give you pointers so you can start looking in the right places when you want to extend your app and you want to secure in different ways with spring security so make you somewhat autonomous or give you the first steps on a journey to autonomy with this Library rather than going to stack Overflow and being very frustrated by this 2013 answer um the focus of today is going to be on authentication so the identity of the users or the entity that log into your app Spring Security also covers authorization but we only have three hours and I want to go a bit deep so we're going to focus on Authentication um we're going to be doing this for the servlet architecture so for spring MVC apps not web Flex webflex is slightly different but slightly similar and so if you have the concepts of this this architecture the server architecture you should be able to find your way through um with webflux apps and finally Spring Security Six is coming out I think in November we're working on this uh so it will be spring security five seven so not the latest latest the bleeding edge I'm not gonna go into my in a milestone for a demo but the patterns I use are forward compatible so you should be able to reuse the same patterns in a spring Security Six application um so everyone here uses spring almost I think so that's good because if you don't use spring this is going to be this is going to hurt a little bit uh so let's get let's get started with this Let's do let's do a little bit of a of a demo if you want to follow along here's some code um I think it's better to watch me watch me do it instead but you'll have the links to this repository at the end of The Talk cool so if we start a spring project we usually go to start.spring.io right and we're going to do a Gradle project we're going to use Java not to be too fancy and this project is going to be devoxx Belgium right and we use Java 17 because it's really cool um so Spring Security is for securing web apps and web endpoints so we use spring web I'm not going to use security right now we're going to be adding it as we go and see how that changes things I'm not adding the dev tools either because it has it does magic for you that I don't want in the demo so we just have a spring web application all right here we go this can go away all right and then make a new thing let me go to Temp we move the thing we've downloaded that I called devox ee here unzip it it's the font size all right maybe that's a bit small all right unzip this there we go here and we open this with our favorite editor yes I trust comes from start.spring.io and all right so while this is indexing you know this is a basic spring project let's wait for the internet to be downloaded perfect so you know it's a web project so we need some web endpoints to Showcase this so we're going to create let's call it web controller it's an awful name but you get my drift um this is going to be a rest controller and we're going to make two pages a public page that everyone should be able to exit to access so this is going to be the default page for our app and maybe it returns hello devils right and then we're going to make a private page and this one should be secured um this should be private and then you put some emojis to show that you're encoding is weird and doesn't work beautiful nice um is that font size okay or in the back is that all right yeah all right uh and so we exposed this over private so obviously if I start this application uh nothing is going to be secured right because we didn't do anything oh invalid release amazing let's restart IntelliJ with the correct Java all right here we go that's what you get for using the latest LTS enter presentation mode all right and so here this should start work is happening wow what do you want from me IntelliJ you want to use Java 17. there you go right start again I'm gonna get there we're gonna get there yes okay some spring logs things are happening and we can go to localhost 8080 that's the default and we have hello devox and of course if we go to the private page it's not private so we want to secure it um and the way to do that in the spring ecosystem is to add the Spring Security dependency and we can do that with a spring boot starter so just like this one let me close this we're going to add spring boot starter security I think that's the right one cool then we re-import the Gradle project and then we rerun the application once the build has finished right starts again and now if I go to private I have a login page well the problem now is that if I go to slash I also have the login page if I try and navigate to to the the root of my app um if I curl it localhost atat I get a 401. it's like it's forbidden you cannot access here this is one of the important patterns of string security and something you should try and replicate in your applications is that everything is secure by default so by default we don't want to expose we don't even want to expose which endpoints we have so everything tells you it exists if I try to go to something that doesn't exist like Foo I don't even get a 404 I get forbidden everything is locked down so to not lock it down um I guess many of you have done this right we're going to create a config class and we call it security config so in the past you would extend web security configure configure adapter this thing as you notice this has a strikethrough in it because it's deprecated and you should not be using this anymore this is not the the pattern the Spring Security team recommends you use it's there you can still use it and it will still be there in Spring Security 6-0 however what we recommend doing instead is we say you create a conflict class and you're annotated with enable web Security even though spring boot does that for you and you provide a bean of type security filter chain right and this one takes an HTTP security HTTP so it's very similar to what you had with the web security configure adapter you just have this HTTP security and the difference is that you have to return HTTP to build at the end whereas you didn't have to co-build with the adapter cool and so what we're going to do we're going to say authorize requests and I'm going to um use the the Lambda configuration model you can still do this uh fluent API that I guess most of you are used to and blah blah blah I'm going to do it instead this is the the new or the the recommended Flavor now so authorized config and we're going to say so what do we have we have a slash page and then we have the private page so if we take the private page and we say we want it authenticated and then we say authorize config the any request permissible so that means if you go to private then you must be authenticated and will redirect you to start authentication if you're not and for the rest just permit all okay amazing so if I do this now I should be able to access the slash page no problem right and if I go to private I have a new problem I have a an error page um and this is usually because the the the the the security filter chain here overrides a default that spring boot gives you and we're missing something here we're missing two things we're missing the capability to log in with a form so we can configure our filter chain and say okay I want also to enable form login so if I need to log in show me a form and then if you go on the internet and you look how how this works you realize that you also have to provide a bean of type user Detail Service which is the repository of users is this where your users are defined so it can be a database right a jdbc user service it could be a file we're going to use in-memory for for a demo so we have an in-memory user details manager new and then in here we're going to put a user with a username user and a password then you have to specify how you store your passwords for a demo I'm going to say just store them plain text but you could have a b Crypt thing and then we would need to have a decrypt hash for example but just as for the demo and then authorities and we're going to say that this person has the role user right and then we build it and we return this so now when we try to to navigate to our page the the fault um slash is still public if I try and go to private I we have our signing form that's here and we can use it with user password right so we have a page and it tells us this should be private but if I'm logged out I can't I cannot access this right so I told you that Spring Security is secure by default so by default it would hide all the pages and what we're doing here is not really in that vein we're basically exposing anything and securing some specific endpoints the idea if you want to follow the the mindset of Spring Security is that you do the other way around so you say the the public page is public and any page that you want to be public say error page the weight label error page the five icon are the usual ones you make them public and then any other request must be authenticated so you reverse this because if we keep the current setup I log out right yes I want to log out if I go to Foo it gives me a 404 so it tells me there's no 404 endpoint some someone can then start enumerate enumerating pages on my site and and Hammer the site and try and find existing Pages if we do it the other way around then Foo would be authenticated so someone would need to be logged in to actually see that food doesn't exist so restart the app again cool so here still public now Foo I need to be logged in user and password right and now I have a four or four because it doesn't exist if I go to private then I have the private page okay cool um then this I can log in with the username and password that's interesting we can extend and we can say oh this is useful for development or is this useful for admins but I want this to use SSO instead so to use SSO we could use open ID which is the I think the most common protocol we have today um you don't have to be familiar with how it works but with Spring Security that's very easy so the idea of open ID is what you have when you have these sign in with Google buttons on your apps right you go to myphotobook.com and you can log in with Google well this is using open ID in the background so to do this we need the libraries to do that so we are going to start oauth2 client we add a starter let's compile this and then we need two things so we need to tell our application that it should use open ID it should use oauth2 login so open ID is built on top of auth2 so we tell the security filter chain oh by the way I also want to be able to log in with oauth 2. and then since we're logging in with Google then not everyone can just log in with Google like this right you can't use Google servers for authentication freely you have to have some credentials and this these credentials if you're familiar with open ID in the application yaml we have we have to declare those credentials so we're going to have a registration we call it Google it's going to have a client ID for now it's a placeholder and a client's Secret another placeholder cool and so we need to obtain those client ID and client secret from Google if you go onto the internet and you say I want um let's make something that's not private I want to do SSO with spring and Google it will tell you then you have to do what I just did and then you also have to obtain credentials so we go on the Google console we create credentials we are going to create credentials for a web application because we're not doing Android here the fox Belgium and then you need to specify this redirect URI it's a well-known thing that you would find in the guide on the internet I'm not going to dwell over this I don't necessarily want to explain the protocol and it gives you a client ID and a client Secret which we can date put in here so the client ID is this one you can take a picture and maybe I forget to remove them after the talk cool and so if we rerun this application again cool and we try and access the private page and I zoom out we have a new Option log in with r 2.0 it's actually opening the under the hood if I click Google here hopefully if the demo got well I guess I could use this yeah I have to log in then this does SSO so it goes to my you know VMware authorized provider logs me in with that then brings me back to Google and then it brings me back to the site and now I am logged in with um the the the open the Google SSO instead of a username password right so I can extend what I use to log in now this is cool right I can be logged in but it doesn't really tell me much about who is logged in so to consume this authentication this this identity of the user and display it on the page what you would do typically is inject an authentication here in the endpoint cool and then maybe we change the message here we say welcome to the VIP room and we're going to have the username and the username is going to come from the authentication which has a get name and I told you you should always put Emojis because this is how you see that your browser doesn't work on Japanese regions ta-da and coffee this is their over developer conference all right and then we start this again cool and if I go to the private page now with user and password it says welcome to the VIP room user and if I try to log in with Google all right and then go to the private page then it tells me welcome to the VIP room 1125033096301488-0558 this is my subject ID in Google parlance um not very interesting so one of the um tips and tricks of Spring Security when you don't really know how to get the information you want you just debug the thing right so we debug this application we log in with Google cool and then we get here and we see the type of the authentication it's an oauth2 authentication token and it has authorities and has details it has a principal principle okay and this one has attributes 16 that's good good good and this attribute has an email in here so I can pull the email out in case I'm logged in with Google so continue this we want to make a method get name amazing and so we're going to check the type of the principle Authentication get principal import optional yes that's fine and then we're going to say we want the principles of type oedc user this went fast but this is what it said yuc user class is it is it an oadc user class than if it's the case then we map and we cast this to our IDC user and then we we can say oidc user get email all right and then or else if it's not a aoidc user so if I log in with username and password we say authentication get name what we had for the user that worked fine uh authentication lowercase a right so if it's a Google thing if it's an open ID login I use IDC user otherwise I use the authentication and we can start this again and now when we log in with Google this is very big okay right it uses my email cool all right so here's the demo blah blah the code right so what do you think of this uh does that make sense is it is it awfully complicated is it too fast exactly it's a bit complicated but not very complicated I agree with you it's a bit complex because it has it touches multiple things as in we had to change the build.gradle to import the correct dependencies then we had to go to the security config right and then change and say oh I want to protect this and this way I declare it and then we have to go to the applications yaml to inject the very secret secrets and then we finally can use it so it has many things that play together um but you can find this in a guide on the internet now if you want to restrict the users that can log into a certain domain then then there's no guide for this and then you have to find out by yourself and it's then it gets really you have to to embrace Spring Security and see how it works to be able to do this so any questions on the demo all good yes yes so in the in will we you will be able to get the code and that uh Workshop there's a Code it might not be exactly the same um but it's it's roughly the same code uh you'll have pictures at the end as well you will be able to get the slides and so the slides will will have a have a walk through of the things that you have to update so here your security config should like look like this Etc um and the code has commits so one commit per step of the things we do together today all right so let's back off a little bit and talk about the the main concepts of Spring Security I I think this the core of what's at what's at the core of Spring Security is the Authentication so the what's an authentication it's what Spring Security produces and that you as a consumer use and it contains it's used for two things it's used for authentication for the identity of the user who might be a meat bag like me or it might be a machine um that is logged into our system and it might be with credentials with a username and password it might be with a complex identity protocol like Samo or it might be with a certificate but it's just who it is the information we have about the user so the email the the dates of birth Etc and then it's also used for authorization is the user allowed to perform search and such action so can I access this page can I post a message can I make an order so as I said we're going to focus on authentication today but it can do both so the authentication object um in in Spring Security this one here represents a logged in user so it contains the principle which is the identity so in here we should have a get principle right and then it contains granted authorities which is typically some sort of representation of the permissions of the user so I I have the role user I have the role admin I have the scope message.read something like this so we're going to be using the principle and it has other stuff inside that as a consumer you don't really care about one is is authenticated it's almost always true so if you if we have made a security config that says any request must be authenticated then it makes sense that any authentication that we get is authenticated right because it otherwise it's blocked it has details inside if you want to know a little bit more about the HTTP request that came in so the IP for example and then it has credentials which is password or it could be a certificate or it could be a token um it's often null because as the consumer of this authentication maybe you don't you shouldn't see the password of the user you shouldn't care about it so Spring Security logs the user in produces an authentication and it's it's authenticated and the password is known and then um maybe one thing that's important is that the principle here as you may have seen the principle is an object so this is how Spring Security is 20 rule right and this is how it's supported extensibility 20 years ago so if you are a library author and you're making a new authentication type you can put anything in the principle so it can be just a string so the name of the user logged in or it can be a rich object this oidc user that we we've seen is a principle and so it has you know it has the the email claim it has maybe the time at which it logged in Etc so this is this has interesting properties because then can put anything and it can put very rich information well the problem with this type of having object this type of coding is then through Spring Security you will be seeing this kind of thing all the time right so do we support an authentication object well only if it's a username password authentication token or a cast authentication token or a cast of searching authentication token which makes it sometimes a bit hard to Grog because then you have to go into debugger and figure out what type um the the principle is and so um it's not the most type safe library in the world it works because it has great engineering discipline inside like things are really checked and really solid and then it gets confusing because this authentication object we have um it has a get principle right but it also extends principle and the get principle is an object so that's that's very very confusing sometimes you will see in some demos in the controller here sometimes you will see a principle injected here so don't do this it works don't do it why not to do it because the principle here is the Spring Security idea of the identity of the user the principle here is not part of string security it's part of java right and so this is the Java idea of what an authenticated entity is Spring Security has more information so that's the second pattern I I think you should respect for your applications is try and use as high level abstractions as possible right so try and use only use Spring Security objects and if you can spring object because otherwise you get very confusing things the principle.get principle if you if you if you've ever written principle here principle and you import this fine then it's a principle here but it's actually an authentication so you cast it cast to authentication principle right and then you have principle the get principle what does that mean you should probably not be doing this and it's not even working like oh it's missing a parenthesis right so this is very very confusing don't do this stay in the Spring Security world use the Spring Security abstractions they're usually good enough for what you want to do and authentication very good cool so for your apps you use authentications and this authentication is an interface right it doesn't have much inside it has you know the the the name the uh the principal the credentials potentially and the authorities right so for your applications you use authentication and then if you make some specific behavior that doesn't imply a user that has a username and a password then you don't use username password authentication token this is the the common thing you do in the beginning because when you do form login you have a username password authentication token and so you try and reproduce it but if your thing is not a user and doesn't have a password it doesn't make sense to make this it makes more sense to create your own authentication class or implementation and you can see if you look at the subclasses you even have testing authentication tokens you have special implementations of this for testing right um so it's very easy to extend only a few methods and we'll see how we do this cool so authentication object what the Spring Security does do with this so it produces that and how is it how is it possible that I get it through this injection in the web controller well it uses something called the security context the security context is basically the holder that has the authentication inside this is only true in the servlet world in reactive it's different it's a global static object that you can access anywhere um and that is alive in the thread so anything in the thread that is processing the request has access to the security context so that means in here instead of injecting the authentication we could do security context holder get context get authentication and we obtain the authentication right and this works in the exact same way as injecting it so why is this interesting why is it implemented this way I'm just still going to test it make sure it works right so we can log in as a user so why is this interesting so it's interesting for you as a user if if you happen to have your controller call I don't know a food service right and then this food service is a component it has a Bar Method that takes a bath right and then in here it it calls the Cox service uh which does blah and then passes bars and so on um if this this blah method um takes needs to have an authentication as well that means that means you don't have to pass it down into five method calls right so you could just get it here where you knit it where you need it right you say a security context holder get context get authentication and you obtain the authentication right so you don't see if you have five five Services Deep nested you can obtain the authentication like this it also allows Spring Security to do stuff like pre-authorized and you say oh it it must have is authenticated and has role admin right and so the way it does this pre-authorization is by looking up the security context extracting the authentication and verifying this this is not a recommended pattern to just do this right this is authenticated has roll admin can be expressed at the endpoint level and we recommend you do this you protect the endpoints and the methods themselves don't necessarily need to be protected but if you have very sensitive methods your 15 people working on the same code base and you want to express yes this must be only for admins you can do some sort of Defense in depth so the endpoint is protected and if someone forgets to protect the endpoint for some reason the method is also protected and this is happening thanks to the security context now if you're remember your your computer science classes or what your mentors told you um you should not be using Global static objects why why does this work here this works because this security context holder is a thread local variable that means it's only available in the thread that's processing the request if I spawn more more threads they're going to talk to database or do more calls it does they do not have access to the security context so if we do a new thread here and so it's a runnable inside and this thing does security context folder get context get Authentication and we're going to replace this one and and we call this one in thread in thread a little plus to show it right and then we do the one out of the thread outside this one is the authentication we obtained from outside and this is the thread T and we do T dot start and T dot join so we wait for the the stret the thread to come to complete before we do the rest fine exception so we run this again and we log in user password and then in here outside the thread I have a username password authentication token right it has a user it has some stuff and in the threaded snow right and this security context holder is then cleaned after the request is processed because the if you use Tomcat so if you use spring boot with spring NBC it's likely that you have a tomcat inside it has you know 100 threads it computes the number of threads it wants depending on the machine and then each request that comes in runs on a thread when it's done some other request is going to use it so the security context must be clean so that the next request doesn't steal your Authentication uh uh cuckoo all right so this is the mechanics of where we get it but usually when you use it you just inject the Authentication right so security context holder contains a security contacts which contains an authentication and it has a principle it has authorities most likely the we're going to care about the principle and this this demo or in this session here today um do we have any questions so far Okay so before we get into coding again we need a little bit more than just authentications because this is how we consume them right but how do we produce them and usually we produce them through the second building block the filter so this is the um the servlet architecture so sort of like containers such as Tomcat JBoss uh weblogic whatever it works like this you have a client that makes a request and the request to an endpoint is going to hit a specific servlet the servlet contains the business logic so if my endpoint is slash orders this the servlet is going to produce the list of orders for the specific user between the servlet that produces the response and the client there's first a list of filters the filters are used to do common things between requests so they're used to do side effects so if I want to log stuff right I don't want to be going into every endpoint that I make and and you know write some logs so I can have a filter that's reused between all the servlets and that log store request they can do pre-processing of the request and so for example they can do authentication so they can read my session cookie verify that the session cookie matches something in database and then load the user information in the thread local thing that we use they can do pre-processing for security reasons so for example if I'm trying to access an endpoint that's not that's protected and I'm not logged in and can cut and so maybe filter one here will cut the processing and this is has nothing to do with spring this is so late now spring has its own way of doing filters so it has this delegating filter proxy that wraps a bean inside and this is mostly for life cycle reasons because the bean life cycle is not necessarily the same as the containers so what you should remember here is that you know spring has its own flavor of filters and so it filters all the way down because Spring Security has a delegating filter proxy that wraps the security filter chain that itself has filters inside and so when you operate in Spring Security you actually operate at this level so it has a concept of a security filter chain which is exactly like the normal filter chain [Applause] but it's a single entry point for Spring Security so when you're trying to secure your app you will never ever write stuff like this the filters on the the main path right on the container you will be adding stuff into the security filter chain so it's important to know that there might be multiple filter chains that have different logic depending on the path you're trying to hit for our demo we're making one and that's enough but you know you should know it exists the concept of adding multiple filter chains so what's interesting about this is that the you can see the filters that are actually wired in your application by going to the default security filter chain if you don't remember this you should remember this is a security filter chain filter chain right then you look at the implementations and there's one default security filter chain and it's it's calling this Constructor here and if we run the application in debug mode we should hit that break point and then we see the filters and we can we can see all the filters that Spring Security is injecting into our application and so if you're trying to understand what's there what's done what's not there why is it missing then you can look at the specific instance of filters here okay so what do what do Spring Security filters look like what's the the general um layout well it's this it has a do filter method takes a request a response and the filter chain object so it's in three phases one before the request this process anything that is an authentication process an authorization decision um the decision to whether this filter should do anything to the request or not so it happens before so when you log in it usually happens in the section one then one once it's done it says yes okay I've done what I had to do then I'm I'm yielding back to the filter chain to continue processing and then once the request has been fully processed so once it has gone all the way down to the servlet and it's coming back up the filter chain we can do some cleanup and usually you don't you don't want to do this as a user it's some very specific filters that do this so for example the filter that cleans the security context does that it says yes the request has been processed the user has you know used the authentication for whatever they need I'm going to empty that thread local thing so that some second request cannot steal the identity of the user okay so one two three very simple and straightforward now as you notice here we do we call change the do filter because this filter chain here is not doing a loop over a list of filters it's not a for loop it's actually a chain of responsibility pattern so we have a filter chain that has a list of filters inside it has a current position for the request it starts at zero so we find the first filter by looking up the filter at position zero and then on that one we call do filter with the request the response and the filter chain itself then the filter does the processing like this and then it calls back to the parent to the filter chain that calls it and says do filter again this one increments the position gets the next filter calls the next filter right so it's not a for Loop it just goes down and all the way back up so the stack Trace if you represent it as as a a call stack it looks like this the filter chain a is going to call the filter one and once the filter one is done processing it's going to call chain.do filter it's going to call the filter chain again same filter Gene and then filter chain a is then going to look up the next filter and call the filter 2 and so on and so forth and so that's why we have the step three here it happens after the other filters in the stack down the stack have done their thing when we go back up we do the cleanup and so this is this is an important thing that you that you need to understand if you're debugging Spring Security because sometimes you will see stack traces like this that may look very confusing it has to do filter everywhere um so first all the filters have do filter so that's why we have different filters here for example the filter security Interceptor the exception translation filter session management filter and so on which we can find here right session filter security Interceptor exception translation session management and so on and then between all these filter we have the same do filter at line 336 in the filter chain proxy filter virtual filter chain so this is the the dark blue coals here when we're calling back to the parent so if you want to understand which filter is being processed let's continue this um it's in the filter chain filter chain proxy all right and then in here around 300 and something there's a do filter and you can see here there's this this current position and the next filter so if we make a request anything Foo right fine go away but cool we can see first it's going to call the disable encode URL filter then we step up it's going to call the current position too so the web async manager integration filter the security context persistent filter and so on and so forth this is how you debug what's happening bit by bit we'll see other ways of debugging this in in the rest of the talk okay cool enough with the theory for now let's take a deep breath relax lots of word thrown at you usually when I teach it's by that point that half my class is asleep I I congratulate you for not falling asleep do you have questions around the filters and authentication so far so the question is what's the reason for not having a loop and instead of having this this chain of responsibility pattern this allows you to do this one two three if you have a loop you do one two right or like one two there's no two right you just do the processing and then you move on to the next one but if you do the the chain of responsibility you Nest things and you say the first filter so let's say you only have these things with Filter one and two so we go to from a to one one calls do filter we go back to a it goes into two two calls do filter then the filter chain a says oh I'm done and so we move on to the next thing here we do the cleanup after the the full processing has happened cool uh another question in the back is the security context extendable uh I I think so I think it's not final um I don't think it's a good idea to extend it or I cannot think of of use cases for doing this it's probably possible I've not seen it in the wild usually you would extend more of the authentication class so how you how to log in and then once you're logged in what you look like but not the Machinery that contains uh the crown jewels and we had someone in the yeah yes it's it's a call in this this uh filter chain mechanism it has um it has mechanisms for that what's really interesting as well is that since you're doing this nested chain of responsibility you can have a try catch around this Dew filter so if any subsequent filter throw an exception then you can catch it and decide what to do with it and if I am not mistaken this is what the exception translation filter does right it tries to do subsequent filters and if we have an exception that happens then you know it will decide Things based on the type of the exception that happened so for Spring Security exceptions right it has authentication exception and then maybe authentication exception is going to say well you should be logged in so I'm going to send you to the login page instead if it's an access denied because you're not allowed to be here I'm going to give you a four or three you're not allowed to be here yes right exactly so so there's a question around uh what happens if we have multiple security filter chain so filter chains Let's do let's go into security configure they're declared as beans and you can give them an order right and you can say oh this one is 25 why not and then I create a new one it's 42. it's going to try them in order in the order of the beans that are declared and now you can say this filter chain here is only for uh API right so first it tries this one is my first and then it tries it says ooh the request that comes in is slash API this filter chain is able to is able to handle it then this filter chain takes it and the subsequent filter change the other filter chains do nothing now if I go to slash login First it tries this filter chain 25 and then it says oh this doesn't match slash API so I'm not going to do anything with the logic that's in here instead I'm going to try the next and maybe you know if we duplicate this one cool and then we call it security filter chain two amazing and then this one is 99 comes after and maybe it only protects Foo so it does nothing or maybe it's for everything and then in that case you know it's the last one it's the Casual now if you do if you mess up your order and you say this one is the number one since it has no filter and it accepts any request this filter chain is going to be the only one that's used throughout the app yes yes so the question is can you specify your user Detail Service for each chain yes you can you can specify um uh you know any logic you want for any filter chain so we we had um a chat with my uh developer Advocate calling Dan Vega he's been doing videos about you know Spring Security lately and JWT Authentication and so we we we simulated the thing where a filter chain had the slash API protection and you could only log in with a JWT token so you cannot log in with username and password and then we make a separate filter chain under you know slash login where there's the user the global the the username password authentication right and so it can be completely separate if you go to that login filter chain and you send it a JWT token it just doesn't work because it doesn't know what to do with it it's not configured for that and we'll get back to uh uh user user detail servicing like this in the in the in the rest of the talk cool any more questions very good so we were at kitties now we get a little bit of energy back and uh we can we can start implementing so it's been a little bit less than an hour is everyone fine if we push a little bit more do some coding yeah okay so I have to delete this otherwise it's going to break everything um we mentioned filters and we said well the filters are important because this is where all the the secret sauce happened so let's make our own um we have a wrap and it has two pages and it has form login it has os2 login very nice now I have a new use case and I want a a robot account a service account to connect to it with uh say a a special header and so how do I do this because form login in here if I had a robot to try and log in with form login then I have to the robot has to download the login page extract the c-serve token from It Craft some requests get a cookie use that cookie to do stuff for my app that's very inconvenient what I would like to do instead is being able to call localhost 8080 the private page and then with a special header that says uh X robot password and I call it with beep boop like this right so if I do this it just doesn't work it tries and redirect me to the login page because I'm not logged in and we want this instead to give us a response if I give the correct robot password so if you've been paying attention here we should be implementing a a filter exactly a security filter robot filter so here we have to implement something if we go for filter this one the servlet one that works we can do it um but first I told you not to do this so you haven't been paying attention that's not good and second you have to implement stuff and the methods you have to implement are init destroy and do filter and so suddenly it's a bit complicated why what what's in the in it what should I do with in it what should I do with destroy so instead what you want to do is go in the spring World instead and the classic filter in the spring work world is the generic filter beam and this goes into the spring framework so we're in safer territory now this is anything that wants to be a filter in the spring world we have more specialized filters for this to find out one thing you can do oops you can do is here go to the diagrams show the diagram here's the class hierarchy of this it implements filter it implements a bunch of things we can look at the implementers of this then the diagram is completely unreadable which is to be expected is it working yes ah I can't seem to be clicking I think I have killed my machine ah there we go uh let's try again fill diagram show diagram yeah okay I can't choose the layout no layout is it graph radial there we go beautiful right so our um generic filter being is here and there's a bunch of stuff um you know filter chain proxy that we've mentioned but you can notice there is another annoying pop-up and uh another interesting filter here that most filters seems to derive from and it's called once per request filter and so this looks interesting because most of the filters we want to do we just want them to happen once per request even if you mess up and you register the same filter a bunch of times so I would recommend go through this one instead okay Boop so once per request filter and when you implement this there's only one method and it's called do filter internal not do filter but you get the ID right so same as a normal filter it takes a request that takes a response and a filter chain what we're going to start with is just say a robot hello from the robot filter right and that's it right so if we run this and make a request I mean I can keep the people that's fine then nothing oh yes let's do a normal request here so we could right then nothing happens because I have created a class but I'm not using it anywhere so we have to instruct swing security to use this thing so in the security config here close this close that we can say add filter if we just add the filter like this it's going to blow up and tell us but where do you want to add it in the filter chain and it's always a good question so one thing one way you can decide it is by remember this default security filter chain that has a Constructor that we put a breakpoint in you can check in there and decide where you want to put it um you can Spring Security Docs you can go in the Spring Security website in the uh let's make it white cool uh you can go in the architecture and it has security filters and then you can see the list of all the filters that um that Spring Security can give you basically you want to hook into something that you know and then this username password is usually in your filter chain if you're doing username password what's really important is that happens before this filter security Interceptor which is basically the thing that secures your endpoint but if you're in doubt username password authentication filter.class is is a good good guess um I add filter and then you have to say before sorry before um the real thing that you really want is filter security Interceptor you want to be sure that happens before this but this is fine it happens before trying to log in cool so run the app again uh line 20 uh you need to remove the animator to API thank you very much so run again and then this right this is happening and we get hello from the robot filter which is good except if I try and go to the normal page that that's not working anymore so if you've been paying attention what's the problem here do filter it's missing do filter exactly right this is the it's not a for Loop so to know to do the next steps in the request processing we have to call filter chain that do filter request response so in here if we go again then everything's normal cool and we have our log which is not what we want to do but you know it's in the filter chain and it hasn't broken anything very good so we need to do our our approach right one authentication decision and then to to the rest trademark um so how do we do this well we get the request we get the header the one that's called X Robot password we say this is the password and then it we compare it to be Boop so if it's equals the password and then this is okay thumbs up else no no so what do we do here well basically we're going to be creating a an authentication and we're going to put in the security context so how do we do this we do security context holder create empty context this is going to be our new context once the authentication has happened and this is one of the other patent important patterns in Spring Security it's uh immutability you don't take the existing context to go tweak the authentication you create a new one and then you load it so in the new context we're going to set an authentication we'll see what we do and then security context holder set context the new context and then we have to do this filter chain do filter I'm going to take it put it here and then just to be sure after this we do return which we don't need to do but if I if I happen to add some code here the return guarantees that I'm not going to do it by accident on on my way back once the all the request has been processed and now we have to decide what authentication we put here so we could do a username password authentication no password authentication token authenticated but then principal credentials authorities it's not really a username and password it's a special robot thing so instead of doing that we create our own implementation a robot Authentication create this cool and then we have to implement the methods so there's a bunch of methods that we have to implement and we'll go we'll go through them one by one so one is the name that's easy and we need it to display this is Mrs robot right okay then we also need to implement um we said the principle in that case it's just going to be a string we are going to get the name so maybe you know it could be a richer object maybe we want the birth date of of Mrs robot but maybe just displaying the name is fine then we need to implement some of those so is authenticated as easy in that case it's always true right we said when we have an authentication it's authenticated cool um so since it's always authenticated then the set authenticated we're going to say don't do that um uh this is again the same pattern immutability we don't change those objects we create new ones instead this is for compatibility reasons and Legacy reasons that we have this set authenticated then we have details well the details that can be null and I can hide this okay then we have what else do we need the credentials credentials that they're most of the time they're known so leave them no and maybe the last thing that's interesting is the authorities and so um authorities utils maybe we say this this one has a special role robot which we're not going to use here but let's make one why not cool and so our filter here in the case we're okay it creates a new robot authentication and puts it in the filter in the security context folder and continues it's not okay we should not process the request further we should say no the password is wrong go away to do this we take the response and we write to the response so first we set the status and HTTP status forbidden right like nope four or three wrong password go away and then we write to the response writer print you are not Mrs not to not Mrs robot fine forbidden cool and since I put Emojis because I'm as smart as um uh we have to set the encoding to utf8 otherwise it doesn't work and we also have to set a header because the browsers don't like it if we don't um content type to be text plain chart set utf8 right so we were basically writing to the response like this and then nothing happens after this return again so to try and make this uh more like one two here the the do filter is in the middle and what we can do is we can invert this and be Boop if it's not equals go away and then otherwise we're okay so we log you in and and we do the next thing in the filter so run this and now so if I try and go to private says you're not Mrs robot with 403 but if we do private with the password be Boop welcome to the VIP room Mrs Robert and if I try a wrong password beep forbidden right that's why you have emojis because it's very easy to read um cool is there a a question with this so far yes you could throw an exception this is more to demo so instead of of writing the response you could throw an exception and Spring Security would do something with it and we'll we'll see that um the the the here you write the response if you throw an exception you'll get just a message that tells you there was a 500 or a 403 it doesn't give you necessarily the details and you have to configure some things so here I want to showcase you can write the responses what Spring Security does you don't have to and usually you don't there's a problem with this application yes sorry yes so I'm doing everything in in this so we can see all the mechanics of the filter in place we can just discuss how to break um there higher level constructs than this once per request filter so a the the the the the thing that uh you would be using if you're doing a lot of Spring Security uh is the using the authentication filter this thing here and it has a bunch of constructs that tells you how do you make an authentication from a request the converter how do you authenticate how do you handle success how do you handle blah and so basically you construct one of these objects and you say these are the different steps and it's already wired in for you the try catch and the stuff around this well we can discuss it at the break yeah learn something did you should not break the chain um that is that is not exactly true um so if we look at one of the filters that we're going to show later um the Cesar filter here it definitely if the tokens are not equal it tells you like no and I'm not going to do the rest because it's securing things right if you're sending data and it's going to get written to a database it must stop so some filters do break the chain and it's it's a normal behavior if you're doing a filter that is just doing um uh you know just logging side effects stuff like that you never want to break the chain because other ways you get this blank page that we had speaking of blank page if I go here now I have a problem my public page is is you are not Mrs robot this is because in every request we extract the X Robot password which in this case is null and we compare it to beep boop but the browser is not sending this and it shouldn't send the password it's a special case so the filter should be a bit more complicated than this first we should check whether there's a Step Zero implied here should we execute the filter right because when we do for example when we do oauth2 login and we're sending a username password form request we're not going to do anything auth2 so the auth2 login says not my problem just do the rest so here we're going to say request get header names we're going to check that there is an extra word password uh right collections make this a list and does it contain yes contains X Robot password all right and we can put this in a nif so if it doesn't contain we're going to do something let's make a field out of this X Robot password initialize in the field everything and we call it header name right and both so if there is no X Robot password we just do filter chain to do filter Quest response and then return that says it's not my problem and it's a very common pattern that you check ooh is this a special endpoint that M should be listening for for you know a username and a password no then I'm not doing anything okay run this again now our public page is still public the private page is still private and I can still log in as a username and a password and in here the BB fails because it's the wrong password and if I try and log in with beep boop then in that case it works and we have a pre-t standard filter implementation this is what Spring Security does yes safer than in your failure check for for the existence of the the password and if it is you set the security contact and if it's not you just do filter so uh the question here is it is it not safer to check that the password exists and matches and if it's the case I set the security context otherwise I do filter well I want to send a signal that the password is wrong so I checked the the value of the password and if the password is wrong I want to do something special and say no this is really you're trying to use the off mechanism but it's going wrong so that when my users come in and try and hit this they don't have a thing that tells you oh you should go to login that tells them oh you're not the robot and it's not working wow you've held for 74 minutes congratulations congratulations everyone I think uh what's what's the time 10 45 I think we can take a let's say 20 minute break 1105 um if you have questions please come along and grab some stickers if you want and see you in 20 minutes foreign [Music] cool welcome back you came back I'm impressed and I'm happy I hope you got some coffee to to go through the second half of the talk all right so before we go into more coding [Music] um a little recap of what we did before the break so we created a filter that makes an authentication decision it takes a request and a response him it reads from the request it can write to the response it creates an authentication object and it puts it in the security context we use the meaning for class not a username password authentication token and then we have to register that filter for with the filter change to this for this to work so this is this is basically what you've seen is what is implemented by Spring Security but for uh production ready example so don't don't do that right don't do be boot passwords in prod so let's let's take a look at a real filter and how it's implemented and one that has some logic in it so the Cesar filter cross-site request forgery protection filter um who knows what cross-site request forgery is 50 60 of the room um so quick explanation of what this is this is a a thing an attack an exploit that is now mostly mitigated by the protection that modern browsers put on cookies um but still um it's been it's been on for a a long time so the idea is I'm a normal user step one I open my computer I go to the bank.example.com website and then I log into my banking website and so when I log in I get a cookie that points to a session ID that says this is Daniel he logged in he's allowed to use the website for two hours or something and I can do some stuff so my browser holds that cooking if I keep my browser open and later on in my browsing session I visit a a malicious website an evil web application that pretends to be I don't know something else something about cute you know cats and dogs and then on the page there is a a big button that says click me for more cats and and I I am enticed to click it the problem is that the button is not just a button like this it's a form in the HTML form and it has a lot of fields inside and there they're all marked hidden but when I and with hard-coded values in it when I click um uh click me on on the website it posts not to the evil website but the form action points to the bank application so now I'm making a post request with my cookie to the banking application with values I have not seen so for example transfer money 500 euros to Daria whoever and so maybe you know I I I I I'm transferring I'm making a payment order um that I don't even know exists I have used this so now this is mitigated with cookies but I I have used this on the same site this the type of of attack so when I was a student we had some sort of internal social network it was more of a open profile page so you would put your name the classes you attended a picture Maybe what you like eating whatever and then it had a blank field at the end a big blind field where you could put anything you wanted included an escape HTML so what I did is I created a like a you know animations whatever and then a form and a button that says click me and the form did a post to the same site saying my name is I love Daniel my my favorite food is eating with Daniel and then the blank field on the person that click clicked me I would inject my own my own form so that it spread like a virus everyone had my click me button in the end um and so the way to mitigate against those type of attacks is um with a special sea surf grossite request forgery token when a legit user makes a request to their banking website they have a cookie they have a session the server generates a token and it says that maybe the value is yyy and it says for session Daniel the token is way way when I am visiting that site and I go on a form it sends me the form but it also puts a hidden field that's called c-surf and it puts the value yyy in it so when I click post it sends the value I typed in the form and it also sends um the the c-surf token so the the the the banking website checks the token and says uh you sent me YY what's in your session it's YY it matches cool I'm processing the request now if an evil website makes a a form that posts to the bank they don't know my token because only the bank can generate forms with a token that's stored on their servers so either they don't put a token or they put XXX and when I click click me then the banking website receives the malicious payload and receives c-surf token XXX it checks what the csorff token in my session is and says it doesn't match this token was not generated by a legit website so this is an attack and we're saying no to this and so the way this is implemented is Spring Security is with the c-surf filter C server filter so by the way this I'm going to walk through the filter but if you want to learn a little bit more about this Spring Security docs are actually a great place to go they're my third favorite place on the internet um after production and start the spring.io of course um so in here if you want to get a condensed version of the stock you go to server application architecture surprise all the the images that I stole um and then if you want to check features here there's protection against exploits and so there's common exploits so one of them is c-surf and it tells you what is a sea surf attack and how you do it and then how how we um how we mitigate against that and then it has protection against other things and and it explains how like which special headers we inject and so on and so forth right so ciso filter what it does in here if we look at this remember it has a do filter internal method so first it checks it tries to load the csurf token from your session basically if it's null it means you had no token before when you made the request so it's going to create one for you and store it right so it's doing something even on a get right if if there's no token for you I'm creating one right and then it says okay does this endpoint require fees of protection because if it's a get endpoint it doesn't really matter I'm not sending data I'm just visiting the bank website so I don't need to protect no one is going to fake my gets to transfer money so here it says does it need protection no well filter chain do filter this is basically what we did in the robot authentication the robot filter was basically no header continue it's fine then it says I'm going to try and grab the actual token from the request so okay we have established that you must be protected here so it means you must pass us a c-serve token so either in a header or in a param we we take it out and then we say is it the same is it the same as what we know from your session if it's not the same then we're going to send uh we're going to throw an exception so we're going to say maybe um maybe missing token or maybe invalid token depending on what you're doing and the Handler here basically it says oh I'm going to say a 403 or show an error page depending on what error happens and then if they were equal then that means the request is legit and we pass to the to the next filters down the chain and we execute the request so what this shows us is that first every filter is kind of the same right it has the same do I care about this request yes I process it okay it's processed was there a problem was there something bad if that's the case I I throw an exception or I write to the response and then if everything's fine pass on to the next second thing that I think is interesting it shows is that you to to effectively extend Spring Security in a lot of the cases you need to understand the protocol or you need to understand the protection you need to understand the attack that we're protecting against to change the behavior because otherwise it's it's bizarre to read this right what this what is this token repository what is what is this token anyway um and then why do we do equals constant time and then what's the access denied Handler right maybe maybe I want special error Pages for sea surf attacks or maybe I want to do a special log right this is a this is a typical case right I want to an SMS sent to me when someone sends a a c-serv token that's invalid then I need to override this access denied Handler they will look at the exception send me an SMS and then proceed with the request or maybe put something in a queue or something so if I don't understand how CSF protection works it's going to be hard to to extend same for open ID right Google login if I if I don't know how open ID or oauth2 works it's kind of hard to like understand where in the chain of things that happen I need to put my code other filters um so you remember we put a break point in the default security filter chain Constructor so we saw the list of filters that were involved uh in processing our request you can also put if you want to debug you can also look at the filter chain proxy and the filter chain proxy and the do filter internal you remember there's this filter chain call so you can put your breakbone here if you want a higher level thing if you have a running app in production and you want to see what's happening and where it's failing and why it's failing Spring Security has great Trace level logs so let's do this in the application right if we do logging dot level and we say everything in the package org Dot springform.security [Music] is going to be at the trace level and we start again it's going to be very verbose so the the the the startup is the same you can notice here it gives you a little bit um the the the the shape of your filter chain here we can see some filters already but what's interesting is that when we make a request and we say let's let's say we make a request with extraordinate password and we put the wrong password beep beep right it throws and says no I'm not going to secure this then I'm gonna fortunately you have to zoom out a bit to read this but it says I'm going to there's a request that comes in and uh it's on the private path or endpoint and oh let's remove the wrap there is what we need to do okay cool and then I'm going to invoke the filters one by one in the chain so disable URL encoding filter is the first of 18 filters then this one way basing blah blah blah security context persistent filter does some stuff okay Cesar filter did not protect against c-surf because it was not it was a get request so I don't need to protect so on and then we get into robot invoking robot filter and nothing happens after this so I have a good clue that you know this should have gone to Filter Number 10 but it hasn't so it's probably because something blew up in the robot filter um same if I try I guess if I try and log in with the um username password I put a wrong password I'll see that I will fail in the username password authentication filter and it will give me info about how it fails so for demo purposes I'm removing this because it's just too verbose and we can't really see what's happening okay any questions about filters in general before we move on to the next section yes ways how to use can you speak about ways to use csrf without a session uh no I can't I would have to think about this um so yes so if you're doing statement so now with the the same site cookie protection you're usually safe with C server um if you really want to do csrf without session um you could there's an authentication mechanism you're using an authentication mechanism so maybe you're using a JWT token a job um and maybe you send that job talking so maybe what you could do is your C server token repository is a mapping between a jot token and a c-surf token right and you could say oh well there's an authentication that comes in and it matches this special token but then that means you would use this c-serv filter here and then you would have to seriously overload this this request right so I have to extract the token make sure it's here and then does it match something in my redis or something but it it's possible uh I think it's interesting to read about the sea surf attack and see if it's a if it's when you do threat modeling are you is it a threat for you if you have the correct same site properties they should be fine cool all right so we did filters now authentication providers uh I I really couldn't think of a subtitle to this so remember the authentications I mentioned the beginning uh I I lied in public um or I oversimplified a little bit about the authentication objects so I said you know they represent a logged in user um and is authenticate is always true and the credentials are always null if that were true then having this is authenticated method would make no sense and having a credentials getter would make no sense either that's because they actually filled two purposes they represent actually either a logged in entity or a bundle of data a bundle of credentials that need to be authenticated to validate that this is a legit entity that wants to log in so they represent either the request to login or the result of a successful login request and this processing of transforming the username and the password into a username password authentication token with the correct properties is done in an authentication manager so authentication manager is a very simple interface authentication manager this one here right it only has one method authenticate and it takes an authentication object in and returns an authentication object usually it's the same so the in in that example here we have an authentication password authentication token a username password authentication token that goes into the authentication manager and then the authentication manager if the password is correct if the user is not you know if the account is not locked if it's not expired it returns a username password authentication token um the the the the objects are the same type the contents are different so the username password authentication token has username and password but the result has the user details so a richer object maybe you know it has the my birth date it has my favorite color it has a kitty Emoji because I like cats and it has the authorities I'm an admin I'm a user I'm allowed to read the messages I'm not allowed to write to the admin console right the authentication manager can either return an Authentication or throw an exception an authentication exception right and that's it so this class is very easy to implement um because there's only one real uh implementation which is the provider manager the other wrappers and the new up which is you know an internal thing for a special filter but basically it's everything is a provider manager in Spring Security a provider manager I think I have a slide for this it's just like the it's the kind of the same idea of the filters but applied to transforming authentication requests into authentic authenticated objects so it's a it's it's a for Loop over a list of authentication provider an authentication provider uh here authentication provider this one has two method it has authenticate and it has support so basically this is the specialized version of the provider manager that says I only deal with username password authentication tokens I only deal with robot authentications I only deal with over 2 login authentication tokens and this allows you to extend Spring Security in a very specific place for changing the way someone logs in without having to write a custom filter that takes the request that does some transformation maybe you don't need to go that far maybe you have special rules around you know the email of the user that comes in well here an authentication provider would be good enough and we'll see how we use that one thing that's important to know is that usually your app has a provider manager so a filter chain has a provider manager inside a provider manager may have a parent authentication manager so if you have multiple filter chains they can have common authentication mechanisms and then separate specialized things and then sometimes it's a bit hard to debug especially with the security config here this user Detail Service is actually swallowed by some configuration somewhere in Spring Security that happens when you do enable web security this one here has a web security configuration and it has a thing or not web security the HTTP security configuration it has a thing that that creates some authentication manager based on stuff so sometimes you don't see all the authentication providers that's because Spring Security created a manager or provider manager for you that so when you when you look at a provider manager you may have to look at its parent but let's grab that for the for this we're just going to do one provider manager and see with this so authentication provider we talked about this and so let's let's see this in practice our website is great right it has two beautiful pages I can log in with username and password with um Google login I have a robot a robot account that can hit my endpoints and get stuff with credentials that are not in the database for example the problem with my website is that I have a an admin called Daniel he's really fine he's neat he's kind he's very handsome uh but he has really bad memory and and for for the for the love of anything he cannot remember his password that's very unfortunate so we're going to make an escape hatch for Daniel so that he doesn't have to remember his password and so we're going to do this by implementing a special authentication provider so let's do this Daniel authentication provider cool so this implements authentication provider right implement the method and we have to implement two methods so one supports so which type of authentication objects are we going to look at with this authentication provider well only username password authentication token uh types so if a robot comes in I'm no I know it's not Daniel so I don't have to check the password or anything so I only I am only going to deal with the username password authentication token and so in here when the provider manager calls this authenticate method it's going to always pass in a username password authentication token or a subclass and so what do we do with this well we say authentication dot get name right this is the name username and we say if Daniel equals the username then we're we're gonna let go otherwise we're going to do something special so if it's Daniel well it's successful like we just need to know uh the the name so we return a new username authentication username password authentication token is your name password authentication token authenticated right and the principle is going to be well the name is Daniel it doesn't need credentials because the you know I don't need password and I'm already logged in and then authorities let's say that we have admin right Daniel zenman so what do we do in case it's not Daniel well we don't know what to do with this like the user password this must be handled by some some other authentication provider so to Signal this we're returning null right so this is this is saying this is the same way as we did with the um with the the filter right do I want to handle this request is it the right type and is the is the content of the payload the thing I care about so we could you know we could um we could we could flip it around and return all whatever um the other thing that the authentication provider can do is throw in an authentication exception so basically oh this account has expired and so you're not allowed to log in you know or the credentials are wrong or you know I don't know the planets are not aligned so you're not allowed to log in today you are only allowed to park on this side of the street on even days of the month and so today you're not allowed to be there so three things right authentication provider returns either an authenticated thing so the result of something that passed me credentials and they said the credentials are good an exception if I want to say stop processing this is invalid this should not go forever or null if we delegate to the rest if nothing can authenticate if every provider returns null it will throw an exception in the end the provider management will say no I don't care about this and so how do we mount it into the filter chain well again we go to the security config and we say hey authentication provider a new Daniel authentication provider like this it will be added to to the provider manager of the chain and it will when a username password authentication token is made from the request and something tries to authenticate it if the name is Daniel we should let it through right so run this in here private right so if I do user blah it fails back credentials user password works all right and then if I go to login again and I use Daniel and I don't look at this then I'm logged in I don't need the password so this is typically what you should be doing in production right no password for your admin cool all right uh so that's the thing blah blah um one maybe one important um one interesting thing about this so why what's interesting with the provider manager is that it has some logic in it and it does some stuff for you so the provider manager for example uh produces logs uh so there is a there is a wiring that I need to do here uh uh authentication event publisher publisher so oh and then we see HTTP get shared object authentication manager Builder right and then set shared uh no it's a shared object and then event publisher publisher and then can I wrap this in a thing like this can I put it here does that work right and then up voila don't look so this will disappear in Spring Security uh five eight we have the patch for this but it's not here if you use the web security configure adapter you don't need to do this but it's fine just ignore it doesn't exist so the provider manager when I log in it produces an event when I fail to log in and produces an event a spring event so that means we can listen to those events and do stuff when an event is done so we create an application listener being of and we're going to look for authentication success events so on uh so uh success listener right and so basically when an event comes in we're going to do stuff so for example we're going to log to the console uh and ta-da all right success and then we're going to put the type of the Authentication and then we're going to put the name can I format that's it right so success [Music] and then here we're going to say the event has an authentication and it has a class and it has a name so we're gonna get the type of the authentication and then authentication get get authentication and maybe we put the name of the Authentication all right so this is just logging as success so if we run this cool and we log in here and come back to private user password right then here I obtained a username password authentication token maybe we'll put a simple name to get a simpler thing cool and then if I log in with uh Google right then I get a all to login authentication token so I can log stuff right I can log successful authentication I can log fail authentication and this is all offered to me by the provider manager by the whole idea and it you know it processes exceptions and it delegates to other so usually when you want to do custom authentications you do a custom authentication provider rather than a full filter so if we want to change our robot filter to use an authentication manager we can do that so we have an authentication manager we need an authentication manager right and then this needs to be passed into the Constructor and so in here it will use the the robot filter we use that authentication manager to transform an authentication request into an authenticated object so in that case an authentication request should be a special type of robot authentication we're going to change this one so is authenticated we're going to make a feel out of this is authenticated right and then the authorities we're going to make a field authorities right because these will depend on on whether this is an authentication request or an authentication object so perfect and then we're going to need a password right we're going to pass a password and we're going to check that password and so let's do a public string get password right and this will return a password uh-huh no I don't want to insert this I want to create a field beautiful and make it final as well okay so then we can make a Constructor uh uh yes and then in the we're going to pass the authorities as well cool add to the Constructor authorities yes fine cool and this is very like when are you logged in well is authenticated is when the password is null so when I don't pass a password I'm authenticated uh and this is too hard for my users to understand so usually and this is what is done in Spring Security you create static methods for this public robot Authentication uh unauthenticated authenticated one takes a password right and this calls return a new robot authentication of let's say collections.empty and the password right and then we create another method for uh robot authentication authenticated and it takes nothing because I don't need to know any details about the robot and it's a new robot authentication and the collections are this the authorities are this and there's no password right okay so we have our our transforming or our two states right of authentication requests the credentials and actually like an authentication request the credential so basically your password or authenticated which is just authorities and so in here we're going to do something slightly different we're going to say uh authentic we're going to extract the password and so we from that password we can make a an unauthenticated are these public yes oh they're not static thank you static think right uh we're going to make an unauthenticated version of this and then we're going to see this is an auth request and then we're going to call authentication manager that authentication of the auth request right and then this is the authentication successful authentication if it works and then if it works then we can put it in here this thing right and then this we want it to fail if the password is wrong so this is going to erupt and wrap this in a try catch maybe rub the whole thing in a try catch try right and just authentication exceptions right so if we're authenticated we just do the filter chain thing cool and if we're not authenticated we get an authentication exception and we're going to handle it and then you are not Mrs robot which is going to get the message instead here the message of the error so now the only piece we're missing okay here we go e dot get message um so the only piece we're missing is what transforms an unauthenticated robot authentication into an authenticated robot authentication if you've been following it's an authentication provider two people nice nice nice nice nice um so we created a robot Authentication provider and this implements authentication provider right we implement the method so supports it's only a robot authentication classes right this this should not try and Fiddle with a username password authentication token or stuff like that and in here we say well authentication we know it's a robot Authentication uh call it auth request and then what do we do we do auth request get password uh huh and maybe we do something funkier we do a private final list string passwords right we do a list of available passwords for our robots port list fine create the Constructor beautiful and then we say if the password but this should be password so passwords there we go yes fine uh if passwords contain the password then we're happy we'll return an uh robot authentication dot authenticated successful else throw new authentication exception and so authentication exception is a an abstract class so we want a subclass of this and here back credentials looks good I think bad credentials exception and then here you are not Mrs robot oh very nice there we go all right and so maybe again invert the if and then in that case we'll remove the else right and so now we have a robot authentication provider that has a list of passwords if the password we pass in is matches one of these then we're authenticated if not we have back credentials so now what's missing is wiring all these things together and we do this again in the security config this is the place where we wire things in so here we need to pass an authentication manager in here for now I'm just going to create one out of scratch and then we'll see how we make this slightly cleaner later so we said authentication manager is always a provider manager and then this is going to pass a robot authentication provider and it has a list of passwords be Boop and then we're going to accept boop beep wow and this should be a list in this wrap copy no so list of this right import me list please quote so we have a provider manager and then call it auth manager this is the typical name and then I'm going to wire the event publisher in it because uh cool and then so our robot filter now takes an off manager right so we did a lot of things we we split the logic a little bit we the logic for transforming a password into a robot authentication now goes into the robot authentication password a robot authentication provider check the password if it works then the robot filter is happy and takes the successful authentication puts it in the context otherwise it catches the the exception and then returns so if I have not messed anything up cool we should still be able to have beep beep boop should work there we go so B boot works root beep Works nice but boop boop you're not Mrs robot and with school with using the provider manager construct rather than doing stuff in the in the in the filter itself and then being very like oh I take the request and I do stuff with the requested to authentication is we separate the concerns and we get free logging instead so now we have login you have you produced a robot authentication for Mrs robot right and so you get all the benefits of the provider manager of logging of authentication success of retrying with a parent provider etc etc cool all right that's a lot to take in uh do we have questions around this authentication providers and authentication managers go ahead oh so the question is in robot provider in support what is uh authentication uh not specified with generics it's just any class I don't know it's probably Legacy reasons this is very very very very very very old like Ben Alex has been gone for I was in at VMware at that time um so I I think it's one of these core things that hasn't evolved in its API right see the copyright is from 2006 and so that that's probably the Legacy reason and it's so core to the to the the architecture that it probably doesn't involve and maybe there are very good reasons that I'm not aware of as well cool all right so authentication provider very similar to very similar to the uh very similar to to the the filter chain right it's a list of things that we try out also if we do tracing again uh this one we reintroduced racing run the app again and we do uh login with login and we log in with the user we also see user password and here we also see that we're securing the we're posting to login right and then this goes into the username password authentication filter and then it tries to authenticate with Danielle authentication provider this one return null so it's not it's trying with the rest and then it's trying with a Dao authentication provider and then it authenticated the user called user so we can trace a little bit more right oh it tried with this is this this failed and so I'm trying this one instead and so on and so forth what's really nice as well with these authentication providers is is security config it doesn't care about the shape of the request right it doesn't care that the password came from X Robot password it doesn't care that you're trying to log in with a post request so for example if we change our app and we say we also support HTTP basic by the way right so instead of making browser calls with a post I'm going to make curl requests and pass the login and the password in it so this says user password this we haven't changed anything or this is not specific uh to our app or to our provider uh ATT private right this works but now I want to extend and also support Daniel anything right and it works because it doesn't care the authentication provider doesn't care about the request it only cares that there was a username password authentication um bag of credentials that was produced by something and then it authenticates it so for free without having to fiddle with filters and usually going more specific is more interesting than doing filters because if I wanted to do the special Daniel filter I would have to check the post request and then I would have to check the the authorization header right with HTTP basic we have a special authorization header so it would have to base64 decoded split the column and so on and so forth cool make sense yes so the the question is um is there a way to so since the the authentication provider can return null and delegate to other authentication providers is there a way to order them um usually there will be only one provider manager it will be in the chain and it usually it depends uh where um where in the filter chain things are declared so if you declare several of those the top the top most one will be at the top of the list basically so it's an ordered list so usually authentication providers you put them here like before other stuff but we'll see with the configurers how how this is done so in here in our filter chain it's going to prioritize form login over HTTP basic over or through login so if I send a weird post request with the username and password in it and also the basic authorization header is going to perform form login in priority if I swap this if I send my post request from the browser but I also add the the credentials in the HTTP basic header it's going to use HTTP basic instead right so if I use Daniel in HTTP basic and user and the form login in that case it will prioritize Daniel and then in that case it will prioritize the other one so the order is how things are declared in the filter chain okay um so now we maybe the recap of this right so authentication it's a bag of data that needs to be authenticated and it's the successful result of this the transformation between a blob of credentials and actual user data or entity logged in entity data happens in an authentication provider and then that's where you should create your own rules for authenticating so maybe you have some special cases around user names or something then you can create your own username authentication password and of course it depends what you want to do but it's usually a very good place to put your own logic rather than creating an entire filter which is very involved so then we get to the very interesting topic of configures configurers are an abstraction that allows you to configure the filter chain and do multiple operations on the the HTTP Builder here uh with one cool and so basically What's Happening Here is that this is calling a special form login configurer we'll get into that later we're going to change our own um our own setup to use the configure instead and then we'll explore the existing configurers so it would be really nice that instead of doing this and having to create a provider manager and also having to add both a filter and also a authentication provider if I extract it for all right we have this like one two three objects for our for our robot account it'd be nice to be some to be able to do something like robot login right so you will not be able to do robot login by yourself um unless you extend the HTTP security class but it's final so you can um so you would need to be able to contribute to to Spring Security to do this to create your own robot login and I think they will say no I haven't tried but they probably will say no however you can apply your configure with a slightly more involved syntax and you say I'm going to apply a robot login configure here and then I have to go and then we'll get into this so This configure created cool this must extend do I get this right abstract extends abstract HTTP security HP configure of your robot login configure and an HP security so oh not Builder HTTP security right so this is a special class that has two interesting methods in it and configure so this is step one in the configuration process and this is step two um so this initializes initializes a bunch of objects and this also initializes initializes objects but can reuse objects from Step One even from other configurors so basically there's a loop here that happens in uh can I remember the class abstract in security configure adapter to configure I am not sure are in the Builder um I I can't remember this one is a secure no I can't I can't remember exactly where it is um but there's a there's a loop um that says like take all the configures that are in this filter chain run in it and then do a special step and then run take all the configurors again and call configure and so basically how this is actually used here you put the authentication providers and then here you put the filters this is like this so this is what we're going to do so our Builder here just for consistency with the rest we call it HTP and so here this is exactly what like when creating a filter chain we can call any of those methods so in our case uh we want robot logging configure we want to add an authentication provider which is a new robot authentication provider I mean some passwords here I'm going to create a list of passwords create Constructor uh design and robot authentication provider take a a yeah it takes a list of passwords passwords IntelliJ you are too slow faster faster faster faster there we go list of passwords make a final list of passwords and string and it's a new arraylist fine and so what are we going to do with this we're going to have a public message here uh that returns a robot login configure and that's called password to add passwords so kind of a builder pattern to add passwords desktop passwords dot add the password right so it's now the configuration of the passwords can be done outside of the configurer fine sorry yes return this here correct otherwise we can't do Builder thank you and then in here we add the filters so we can add a filter before and then this is going to be a new robot filter all right and then we are going to add it before yeah I don't know username password authentication filter class why not or maybe security filter interceptor hello filter interceptor uh no filter interest security Interceptor I got my thing in the wrong order okay cool and here we need an authentication manager now the filter chain has one in here and so we can get a shared object of class authentication manager not Builder just manager class import it authentication manager so this get shared object is Spring Security re-implementation of application context in spring so it's kind of beans you have this this like repository of objects and you put things in them here all the authentication providers are populated at init they're put in the Builder and then we call build and then an authentication manager is made to be reused in later steps this is because each filter chain may have their own authentication manager so you can't just have beans because that would be global Okay cool so now this is implemented it's very simple we can use it in the security config and so instead of having all this right the robot login configure I'm going to extract it we don't need an off provider anymore right because this is done in the configure and so now we could say the configurer has a password beep boop and a password boop beep right and this is exactly the same as what we had before so if I run this and I haven't broken anything which is not guaranteed uh we could do B Boop and it works beep I guess and if we do Boop that still doesn't work all right um why is this interesting and what how what what pattern do we recognize with this is in here if I decided to apply the new robot login configure here when we look at the return type of these things this returns me a robot login login configure apply it here takes a configure of type c and returns a configure of type c and the configurer which is the security configure adapter thing has somewhere in its hierarchy and and method that returns a builder that returns HTTP security basically so here we go back to http security so with this I can do a DSL I can do password beep boop and password would beep beep and this is exactly what you see when you do uh go away project view cool when you do form login here and you do a username parameter is uh and the password all right and the next right so you can do the same thing you can do the same kind of DSL even though now that's not the recommended way of doing it so let's look at the ways the recommended way of doing it is this is what we've done right we apply it so form login configure I can apply it in three ways I can do http.form login and then the fluent DSL that we you were used to in the past before 5.7 or 5.6 um you could create a formula login configure like this and then call login page and so on and so forth and then apply it and call end or you can call form login and then password Lambda that takes a configure and changes it so basically doing all the thing after it's been created so it's just a uh it applies this this consumer of um of a form looking figure why is this interesting this Lambda DSL this is because this matches what we have in koflin so does anyone do kotlin spring here one two three four five six yeah it's pretty cool um I like it I like kotlin spring uh even though now with Java 17 we're getting closer to kotlin but you can do this kind of DSL and it reuses the same mechanism of the um of the the the Lambda so this is the kotlin equivalent is the Slender here and you've seen me call with defaults a bunch of times here with defaults is a cheat it's a function that does nothing so it's just to call the correct method so what defaults is very it's exactly the same as doing a Lambda it takes a configure and does nothing with it and it's the same as calling form login Dot and HTTP basic.ncsurf.n one after the other cool okay do you have questions about the configurers yes no now with a no so we cannot support the Lambda style um but if you want to do something that pretends it's a Lambda you remove this parenthesis here and you put it here and so it's not a Lambda but your object with the builder style is already inside the thing but so um cool so now that you know this that the the the HTTP security filter the security filter chain is configured through configurers and those configure are applied with these Special methods because when we look at it this is a all through login configure then you can go and navigate Spring Security yourself and you can go and understand a little bit what's happening so for example here's the oauth login configure and it tells you things it tells you this is for or to login using the auth2 authorization Grant flow and it uses it needs an account with either an oauth 2 provider or an oidc provider and it's going to create this filter here and this filter there is going to create these other objects and it's going to reuse the client registration repository so if it's if it's if it's not present it it's going to explain this one is optional so it may create one for me so I can see a little bit the classes that are that are used if I want to learn about the details and not the lies of the documentation I go into the uh init method and in it you will see a lot of authentication providers so if I try and highlight those right so I create authentication providers and I customize them and then I put them in a filter chain and then you can see oh there are two authentication providers here either an or through login authentication provider or an oidc authorization code authentication provider and here are the things I can customize and to learn a little bit how they go and what they do and then if you know the auth to protocol then you can go into the authentication provider and decide some stuff so for example oh this authentication provider it checks whether there's an open ID scope if that's the case it returns null because it delegates to this other provider and so you can go and start unpacking the different authentication providers so how to transform authentications and then in the configure method you can see the filters that are added right so if I look at filter here I can see the different filters that are created and I can then open them and look inside and there's necessarily not that much in a filter usually even though sometimes you need to know the if you want to understand the work through login authentication filter it will be much better to understand the auth2 protocol because we do a bunch of things inside because the protocol is complicated foreign but usually it's followable and this is how I learn just reading the docs is usually not enough if you want to customize some tweaks and very specific things okay questions okay so there's one last thing that I want to show for sure and we have time beautiful uh security config now we have a new use case on oauth and we want to extend the existing behavior for uh oauth login and I want to allow Only One login per Google user per minute so if you try and relog in multiple times I want the application to tell you oh you're going too fast now this would be a bit complicated to do like like with a filter it doesn't really make sense so we have to plug into to plug into this ol2 login mechanics and there are multiple ways of doing it but if you remember when we are in the web controller that's not the web controller hello we're in the web controller oh we already have a breakpoint amazing you go away here so far and then we go to private here and then we log in with Google oop we get here and so when we're logged in we have an auth to authentication token so the the type of authentication is an auth2 authentication token so I can navigate to that class well to authentication token right this one and then I can say who uses that which classes use this and a bunch of classes use this but what about the classes that say provider in them provide uh wait I got the name wrong I think my bad uh uh I would go with the default oidc user my bad default YDC user so oh and these are the user service let's start with a token instead all right so you who uses the default uh authentication token so I would expect a a provider but there are no providers here so instead I'm gonna try my luck with something that I know a filter right and the filter here does some stuff with the um or through authentication token attempt authentication and what does it do how does it convert well it takes a thing that's an authentication result and that's an oauth to login authentication token so another type of token so let's look at this and do we have providers here yes we have providers and so we have authentication providers that take and off to login authentication token and take that bag of credential and make an authenticated thing out of this and so we have or2 or open ID so in our case it's going to be open ID and so I would like to change this open ID behavior and had add some rate limiting now to do this I could create my own class and so in here rate limited authentication provider now there are several problems with this so if I want to extend YDC blah blah blah authentication provider then I need a Constructor and then in here I need some very complicated objects or some complicated generic objects right the oauth to access token response client maybe I don't really know what this is and maybe I don't I don't want to delve into this like what's the default how do I make one if I want to make one myself so instead what um what we do is is we're going to to ask Spring Security to wire this for us and then we'll just add or sprinkle our behavior on top one other problem you might have when you want to extend Spring Security is that some classes uh are final so you cannot extend them and all the classes we add in Spring Security currently are final so you cannot extend those so usually the pattern you use here is composition instead of of uh inheritance so here this is an authentication provider so it implements authentication provider right these two methods and it's going to wrap around something that's provided by Spring Security and it's going to wrap around an other authentication provider in our case an oidc authorization code something something provider and we call this delegate this must be passed in some way and so support is going to support the same thing as the delegate right so here in our case the oidc blah blah blah supports oauth2 login authentication token so we're going to support those as well and basically we're going to ask the delegate to do the authentication for us and this is the parent authentication so it does the authentication and then we decide you know like is this have we hit the rate limit yet or have we not and so maybe we can say oh if if I can update the cache with the parent auth then then that means I'm fine right uh and otherwise I return maybe I throw throw new credentials whatever uh cowboy not so fast right and so there we have to do this Logic for caching in terms of Boolean apparent off beautiful so maybe this is implemented with a very um secure and scalable concurrent hashmap of string to instance right a cache instance no s go and a new concurrent hash map cool Implement instant it's going to be a map that's enough and so what do we do we do map the Cash Cash dot get apparent off we'll do them by name all right this is a previous instant and now is now right so and then we update the cache so we put a parent off get name and now and we can return so if the previous instant is null that means there was no entry in the cache so we have we this is fine and then otherwise we can check the previous instant the previous login maybe we call this previous of time right and so if the previous off time plus one minute of a minute one is before now right so if one more than one minute has has uh happened uh since the last uh since the last login then then we returned true the update was successful or the the it's fine so if we can log in cool if we if we have logged in too soon we throw new bad credentials exception okay so now we need to wire this in and so we need to pass a delegate an authentication provider delegate and that means in the security config again so in here we could add an authentication provider authentication provider a new rate limited thing of a new IDC but if we do new IDC we have the same problem I don't know what to put for the all two access token response client so to do this I could go into the login configure the all through login configure and then look at these what are what are the default for the access tokens or a token response client right like what's the default it's this so I could do that but instead what I choose to do is change a little bit the oauth to login configure because if I go into here and I look at the uidc authorization code something something provider my authentication provider here it creates it it changes some stuff and then it adds it to the filter chain after calling post process on it and post-process is a thing that allows you to transform object that Spring Security has wired for you and so what we can do instead here is the oauth to configure we're going to extend it and we say well to configure with an object post processor of authentication providers so we're going to update the authentication providers and so in here we're going to return a new rate limited authentication provider of object and we need to cast the stool right and so basically here what we're saying is that we're telling string security do your wiring do your stuff once you're done and you have a nice object I just want to take it and add a little bit more on top of it and so I'm I'm taking it and I'm wrapping it in my own behavior in my own rate limit and so if the if I'm not too tired and the demo gods are with me we'll see uh so now I should be able to log in Boop the Democrats are not with me um this is probably because this thing can be no right this can return null if parent off there's no return no if it doesn't know what to do with this let's try again [Music] uh localhost 8080 and then private and then demo girls are you with me okay I can log in but now if I try to log in again should go into my provider and tell me not so fast right so I have extended what Spring Security gives me without having to worry too much about the defaults and how it applies different things by just wrapping a thin layer of very perfect caching on top of an authentication provider and so this as you may have noticed I take any authentication provider so we can make anything rate limited if we wanted in the security config our Daniel authentication provider could be could wrap around this and then we could do the same for the form login for HTTP basic for everything we want we can just extend and and transform the types of objects we have so a practical use case we have with this um I work um in tensor spring I work on the app SSO team so VMware has this layer on top of kubernetes the tensor application platform and our team is providing SSO capabilities to Enterprises and our authorization server they give you tokens but then the authorization server itself can authenticate you with open ID providers with ldap with saml with username and password and so we have different types of authentications that come from Upstream providers and we save them to we save the tokens to a database so what we do is we extend each of these authentication providers the saml authentication provider the open ID DOI DC authorization code authentication provider and we take the object that was produced and we transform it in an app assistive authentication so to the consumer part or application everything is an app assistive authentication right so in just by changing the little bits extracting we know where to extract the I don't know the the roles of the user we know where to extract the email and so on and so forth so that's one use case do you have questions apart from can we go now please yes who made a release like so the question is is an observation first that there are many ways of doing of achieving the the same result and so this might be confusing this is why you're all here I guess uh and the question is are there plans to simplify this a little bit um yes but it's probably not going to be simple as you want because we have we we have hundreds of thousands of users and out of these hundreds of thousands uh three use this one little entry point thing here and four use the Handler and and so we can't there this would be too much breakage it's not the philosophy of of Spring Security and so I think it's not it's not planned for his 6-0 and I I don't I'm not seeing plans of reworking the entire model for 7-0 so it's gonna be complicated for a while before more questions one last thing that is interesting that you should know exists remember when we did uh the the the first example and we had the form login right like I just included Spring Security and then had a farm a form login and I could log in with a username in a randomly generated password where does that come from that comes from Spring boot spring boot has Auto configuration mechanisms and it's interesting to know where they are to understand what they do and how they do it because they do sensible defaults on a bunch of things so for example here if you know the oauth protocol that's not that's not enough to perform a full oauth flow you're missing information here actually if this was called Foo instead of Google my app would not start right because Google is a very special name we know stuff about the Google login that will never change and this is encoded in Spring Security and Cold by Spring boot where is this so there are two ways to find this so either you go through the security config here and you're like okay I have a or to login that has an all through login configure and it has a bunch of objects in it and I I want to be looking at the objects that are not filters and not providers so repositories that's okay that's a good start so I can navigate to that and look for usages and I would have to look into something that has configuration in it and that is in Spring boot so if I look for configuration right I have these hmm okay oauth to client configuration that looks promising okay not that much I'll try the other one use it sorry usage configuration all to client report repository configuration oh we're in Spring boot which will configure that's a good sign and what do they do well if the user has not provided a client registration repository then spring boot is going to create an in-memory one for you and how does it do this well it's going to read the or2 client properties that you can go and see and you can see that oh that's the Spring Security or to client if that rings a bell application yaml right Spain security or to client so this comes from Spring boot it reads those properties in the auto configuration and then it does something with it so it does a bunch of logic and I can go and drill in here and I can say if I take the time I can say oh get common provider it's in common R2 provider and then boom a magic Google enum that has a bunch of information we know about Google so if you use Google so this is in the spring boot docs you could find in the docs but just by reading the code and following how does it transform my properties into something that Spring Security uses you can find these things oh we know how to support GitHub which is not open ID it's oauth 2 and so it has a user info URI which is different we support Facebook and so on so this Spring Security supports or like maintains those URLs and then spring boot does the automated wiring for you if you want to find the automation through spring Boot and not Spring Security so you remember we have in the build.gradle we added this spring boot starter all to client so that's not that's not where things are this is just a dependency resolution jar that has other dependencies all the magic happens in spring boot Auto configure so you can go into oops in your into your editor download the sources for this and then look inside and look at all the things that springboot can Auto configure for you and since we're doing Spring Security right you should be looking for security and then we have oauth2 that looks promising it's not a resource server it's client and we we import it all to clients so we go into client reactive servlet so we're doing servlet and so I only have three classes to look through this one is the shortest name so probably in this one and so I can check okay if I have a client registration class in the class path then I'm going to end the server as a servlet server then I'm going to import these two things and then we go back to that which was the client registration repository we found through Spring Security and so here you can understand what opinions spring boot has for you it's in the docs but if you want to see the code and all the transformation that happens because this adapter here is still you know it's 150 lines of code so it has a bunch of opinions then you can go in into this one package okay I'm I'm going to stop torturing you with this because it this is way too much um so here's the code the slides the me on the internet come find me after a talk if you want to chat come find me during lunch at the um tanzu VMware tanzu booth in front of the cloak room uh and I don't know what time it is we have four minutes so if you want questions for the end wow everyone fell asleep it's so quiet well thank you very much have a lovely rest of the conference bye [Applause]
Info
Channel: Devoxx
Views: 15,539
Rating: undefined out of 5
Keywords:
Id: iJ2muJniikY
Channel Id: undefined
Length: 155min 59sec (9359 seconds)
Published: Wed Oct 12 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.