RSocket Messaging with Spring

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello hello everyone welcome to our talk our socket messaging with spring my name is Ruslan and here with me today we have Bryan and Rob the three of us worked on the our socket support that we're going to present and that's why we're here today I am a committer on the spring framework team I handle a lot of the web related pieces so spring MVC spring web luxe web messaging Bryan hi I'm Bryan I'm working on spring framework and spring booth especially on the web parts and I'm I've been also working with with Ross and Rob on our circuit support in spring hi my name is Rob Lynch I'm the project lead for spring security and I've been mostly focused on as you guess the security aspects of our socket cool all right well thanks so I'm going to what we have for the agenda today is I'm going to start off by introducing the our circuit protocol I'm not going to assume any prior knowledge so this is probably the key goal for me is to make sure that you have a mental image about the protocol so you can understand the rest I'm going to show a little bit about the programming model but I'm not going to get too much into it because right after me brian is going to present a pretty cool I think spring flight's sample so that will give you an opportunity to see more of the programming model in action and he's also going to talk about the spring bootie integration and then after that Rob is going to come on stage and talk about the security integration and as the joke went around just like in real life we'll see if we have time for security but we agreed that we should have time for security so just a little bit of historical background here two years ago after spring 1 2017 we had just released spring Furman 5 and we were very excited about this protocol called our socket and the reason we were excited about it is because it enabled new opportunities for communicating remote communication and reactive streams was involved in doing that and as a result of that we thought of it as very much a continuation of the work we had been doing with the red flux in reactive programming I do want to ask actually a few questions just to find out a little bit about the audience here could you please raise your hand if you have used the web client or any comparable reactive library ok quite a few hands that's great to see what about just familiarity so those who raise their hands you can keep them down raise your hand if you know what reactive dreams is and you are familiar with the concepts ok very good so I think we're pretty much on the same page so with reactive streams basically we have this community our socket we have this communication protocol which is similar to other RPC mechanisms but what was exciting to us about our socket is that it was a little bit different in that the way it did things so one of them was definitely react to streams as I mentioned we had been working on reactive streams within the JVM to make sure that components can interact and not overwhelm each other but here we have the ability to actually do that across the network so that was kind of very interesting and very unique also reactive streams our sockets had implementations in multiple languages but it didn't require code generation so that was another thing that made our sockets stand out and make it quite interesting to us you can have the code generation on top if you want but that's an optional layer our socket just focuses on the important bits and from those implementations the Java one is actually based on project reactor and you know that was great for us because we were already choosing project reactor we had chosen it for Spring Framework and spring wet flux so that made it very attractive to us our socket wasn't tied to a particular protocol like HTTP 2 or the web so it's pluggable transport layer and last but not least our socket was already in used by some very large companies and it was designed by some people with a lot of knowledge in how to write network protocols and as you will find out when you take a look at our socket IO the protocol is very well laid out and very easy to read which again makes it stand out that's not always the case how well things are spelled out so fast forward one year our socket is now in the reactive Foundation which is a Linux Foundation and you can see that there is broader participation even that's where we expect the reactive streams itself is going to be as well and fast forwards one more year to today we have support in all of these either already we have support or we have upcoming support in all of these spring projects and the ones we're going to talk about today our Spring Framework Spring Security and spring boot okay so I'm gonna get into the our socket protocol but before we begin just one little you know prefix preface or disclaimer so you will see a lot of comparisons between our socket and HTTP and I think that's a natural way to think about it and I'm personally going to also make comparisons with HTTP today because that's a good way to learn about something new but I want to caution against taking that comparison too far while it's true that our socket enables some new things where HTTP that you cannot do with HTTP at the same time I don't think of our socket is a strict superset of HTTP in other words it's not something that you will just go and replace HTTP everywhere and just get more so there's two sides to that first of all it's not everywhere of replacement and number two it doesn't necessarily match all the features of HTTP either HTTPS really good for communication on the web between very loosely coupled very different agents that talk to each other there's a lot of new ones features about content negotiation about caching with proxies in between that's really what it's made for whereas within the firewall I think that's where our socket shines because it gives you new opportunities for how to do things if you're you know doing micro services and you need to communicate between remote nodes I don't want to pigeonhole it right you can still use our socket over the web but I just want to you know give you this a little thing to think about that as we compare to http don't think of it as a replacement that really they each have their own strengths so what is our socket with that in mind so I'm going to start with a kind of a relatively simple definition that it is an application protocol for multiplex and duplex communication does that sound familiar I remember a few years ago when we got so excited about WebSocket and those are exactly the things we were talking about duplex multiplex communication the thing about WebSocket however is that it's very very low-level it's pretty much TCP with framing and you need a messaging protocol on top to to start to do meaningful things you need some infrastructure and that's where our socket actually is a lot more than that it's it's an application level protocol it provides a lot of features it runs on top of WebSocket but it isn't tied to WebSocket so I can use our socket over the web with WebSocket or if I'm inside the firewall I can use it with TCP so it's not married to any one particular transport so what are the features so we're gonna go through those features and learn about the protocol in this way what can we do on top of WebSocket with our socket so first of all our socket is a multiplex provides a multiplex education with for interaction models and what this means is that we're gonna have a single physical connection and then we're going to be doing a lot of requests on that sort of like HTTP - and what these interaction models the first one is going to be easily compared to HTTP because it is a request and response and you can see here those are the actual names of the frames that were that are in the protocol the request response frame is actually very similar to the payload frame but it has a different name because it tells you what kind of interaction you're going to be performing that's because we have other interactions so for example the next one here is a request stream so this one you have one message like an HTTP the request body going to the other side and then the other side is responding with a bunch of distinct messages so this one in HTTP you might compare to server sent events except it's not one stream it's already broken down into distinct messages and and they present it in that way to the application so that's built into the protocol in addition as we will see there is back pressure which is layered into this so not only is this broken down into messages but it actually works well with back pressure so we can tell the server to slow down or stop publishing these payloads and as we will also see this can be done from both hands so you know there's similar to ACC but also quite different the next interaction is a request channel this is where both sides are going to be sending streams of messages and you can see again that the first one there tells you the name of the interaction the request channel frame and then after that both sides are basically continuing to send payloads now I want to put a reminder that we're talking about a multiplex connection so don't think of this channel interaction as a way to kind of do many things you can still do request response you can still do request stream it's a multiplex connection already so this use this only if you actually have a scenario where both sides to stream to each other and then there's also a fire-and-forget so this one is without a response you don't know whether it was handled when it was scandal this is just a fast way to send something to the server and that may be okay in some cases so all of these for interaction models you can actually do them from both ends so this is where we start to also see new things that we cannot do otherwise that's a duplex communication so typically what you will have is a client connecting to a server and then making a request any one of these kinds of requests and then the server is responding to that but the neat thing is that actually once you have the connection the server can do the exact same things so the server can initiate the request any of those for interaction models and then the client is responding so that's basically the reason why in the our socket protocol there is the notion of client and server because initially the client connects to the server to make the connection but once you have the connection the protocol calls them requester and responder because they're completely symmetrical either side can be a requester and then the other side can be a responder so that enables some interesting possibilities which we're gonna see I think one of those in the sample that's coming up mm-hmm okay so the kind of like the main feature of our socket here support for reactive streams so what this means is that whenever you have a streaming interaction so that would be a request stream or a request jennel if one side is streaming a bunch of payloads to the other side we don't want the consumer of these payloads to be overloaded so that's where the initial frame in this case the request stream is going to indicate how many payloads should be sent and after those two payloads the responder has to respect and wait for more demand it cannot produce any more payloads and a little bit later or a lot later the requester can submit another frame requests n frame and that indicates more frames to be sent so you can see here the backpressure in action in fact this is the same reactive streams protocol which governs how reactor project reactor and others work except these semantics in this case are implemented and built into the protocol so the signals that normally flow between the components in this case are flowing between between one side and the other is request frames so cancel on error all of these things are built into it alright so let's take a quick look and this I haven't shown any of the spring and Java implementation yet so I'm not going to focus on what the client sub side does but I will mention that there is a CLI for our socket so you can run these commands from the command line what I'm gonna do in this case is I'm going to run a server so you can see that with a - - server and the - I means input so the server is going to whenever somebody connects to make a request is going to be responding with the data that I'm giving it in this case I'm pointing to dictionary words and we're gonna do - - debug we're gonna do this on a TCP localhost port so the server should be that should be up and running now and now what I have on this side is I'll come back to the details of it but basically we're going to connect I'm gonna look at the frames what's happening okay all right so we connected to the server and you can see there's an initial setup frame which actually helps to communicate some settings parameters for the connection and I did not specify any demand from the client side so the server is not sending anything these are just keepalive messages that you can see here so now I'm going to express demand of five and over here you can see in the beginning that we got a request stream and then that included five and so we got five dictionary words back and you can see those here as well now I'm going to ask for one more and you can see the request end frame so the client sends the server requests 10 frames says give me one more and the server responds with one more or I can say give me 15 and I get 50 back so this is just a very simple demo to show you back pressure in action and the frames that are going from one side to the other but because we will be using reactor just like in a actual reactive application normally we don't typically deal with back pressure directly and explicitly the same thing is going to be true here we're just going to keep writing and expressing arrow logic with flux and mono and the back pressure signals are going to be transparently flowing between requester and responder another cool feature is session resumption so if I have one of these things streaming right if I have connectivity lost then I've produced and pushed a couple of items but you know that's all I've been able to do well there's a cool feature where the client tries to reconnect and when it reconnects instead of starting all over it sends a resume frame and the client and server understand where you left off and then they continue sending so the cool thing about this is it's completely transparent and the server from a programming model perspective you don't have to do anything for this to be supported just the connection can drop off and the can reconnect and it just resumed and the other thing which is nice about this is that because of the back pressure it means that there isn't a lot of caching required to make this happen so eventually the back pressure will make it stop producing and you only need a little bit of cash in order to wait until the session resumes and then you can continue from where you left off now the back pressure is for individual streams what about the total number of streams or the total number of requests that we can have on a connection well that's a feature called leasing and that allows the responder to send to the requester a lease for a certain number of requests that can be made and that allows the requester to make as many requests so that's like requests rattling basically and can be applied from both sides also there are features like fragmentation reassembly as well as heartbeats these are kind of low level fundamental features that are necessary for this kind of connection-oriented protocols that are supposed to be long-lived ok so what's in the messages here you have all the request interactions at a glance pretty much all of these are quite similar in format they both contain data and metadata so what kind of what is metadata both data and metadata are we express how they are formatted through mime types so for example there is one our socket extension that defines a routing metadata and you can see that there is a mime type for that and that tells us where the message is going which could be a simple mapping for the server side or for the responder side or in the case of spring' Cloud Gateway or if there's you know maybe it's not from A to B but there's some routing in the middle there might be some more things in the routes composite metadata so anytime you want to do more than just the route if you want to do security and routes and tracing and Metrix other things then you will need composite metadata and that basically means that you can have multiple types of metadata in it each with its own mime type so again if you look at all the request interactions at a glance the first frame in every request is going to be the most important one in terms of metadata because that contains routing security for that interaction so we're gonna say okay here's the request response here is the route for it so we know how to handle it on the other side and here's the security information so we know what the authentication and authorization organization should be for that all the other payload frames they can carry metadata but we typically don't look in that that's just something that's not typically required so how do we know which metadata mime types were using or for the data well a client and server agreed to that in the beginning there's a setup frame in the beginning which the client sends and the setup frame contains the conditions for that connection and the server can agree or if it doesn't agree it can close the connection but basically it's just a one-way frame that defines the connection and then after that each side can begin to send make requests to the other okay so I'm going to talk a little bit about our socket Java the Java implementation for our socket is very very minimal in terms of API surface its main goal is just to implement the protocol and as you can see here we have one main contract that expresses the our socket interactions so we have request response request stream or question all fire-and-forget if we are going to be sending then we get this our socket and we use it for sending if we're going to be responding then we get we have to implement this interface and register it and that's how the responding works and of course if you look at the API this payload I mean that's basically giving you raw data and metadata so there's a lot of room to make this nicer for application development but again that's not really what the Java implementation wants to do it just wants to provide a minimal foundation and you can also see from the signatures that it's using reactor flux in mono and that's great because we kind of already used to working on that level and because it gives us a declarative programming model that deals with the backpressure internally so just quickly to show you an example of how you would start a server you can see here we do that through the our socket factory and then there's this acceptor and that's the thing which accepts new connections we're gonna return the responding our socket from that so that's our implementation of how to respond to interactions and we're also given the setup which tells us about the connection and we're given a requester that we can use to talk back to the other side to the client and then from a client side well it looks identical actually but as a client we can also be a responder so you can see here that absolutely symmetrical setup is in place and now we can use the our socket factory to set up quite a few other things about the connection you can set up interception you can set up the heartbeats intervals you can set up metadata formats you can specify a lot of things here but we were just showing a minimal example so finally for the Spring Framework support thankfully that's fairly minimal as well so I'm just gonna show up quickly and we're gonna turn over for the sample well first of all we have an AR socket requester and that wraps that our socket contract that you saw and it gives you first of all a fluent API instead of a template and it also gives you higher level objects you can work with higher level objects and the the coding and decoding is automatically handled and then for responding currently we have support for annotated message mapping methods so if anybody's used dumped over WebSockets or you could have used them with JMS these message mapping annotations could be familiar here's an example this is a controller annotated class although the controller annotation is something that you can customize you know if you want to use your own and call it our socket responder or anything else you can do that so that's an example from the snippet from the sample you can see a message mapping method which is responding to requests notice that there isn't anything that says request stream that responds to request stream interactions but you can tell that from the method signature it's taking one thing and it's returning a flux of many things so that's sort of implicit you know it's not like a rigid contract and that's an example of using the requester so here we get the our socket requester builder injected that's what spring boot actually in this case in a sample and we're going to use this requester we're going to connect to a server and then you can see that we can use it to make requests down here we're getting the requester and we're making a request with a route the given route and then we're passing some data to the other side and then we're returning retrieving back airport locations but I'm gonna turn over to Brian now who's going to show you a pretty cool sample with a fly traders and flight tracking so so we're going we're going to see our socket but this time in the context of a stream good application and a sample so first we need to talk a bit about the the use case in the sample so in this case we're considering airport radars so for example Austin's Airport radar each radar is collecting data about aircrafts flying around within its range and let's say it's sending all that data to a particular application which is our radar collector application so this is a spring good application that will collect all the data from many many airports and it's also got a local database with a list of all the airport radars it knows about their name code geolocation and so on so for the purpose of that demo we're not using real data of course we're generating that and I'll show you that quickly so once we've got all this we're able to expose that as as endpoints I services using ours forget over TCP and with that we've got here four examples of routes that were exposing we've got located radars within so within a particular pair of coordinates we want to have all the radars that are within that zone we can then ask about a particular radar its information or we can even listen the radar for all the data on the aircraft that are flying around now the ultimate goal would be to have a an application that a browser can connect to and we'd like to have an interactive map where you could see the radars the the airplanes and and everything real-time plus some contextualized information because you want you have a user preference you have user profile and you want to have like your your personal profile and and other things so that's the the demo and on the flight tracker side of things we'll have some services so the usual with having the radars in the particular zone and listening for many many radars this time for all the quality aircraft signals and we also have new services like fetching your own profile or fetching the profile information from something for someone else and this time because we're using a browser then we're not using the TCP transport but the web socket transport so that would give us a quite interesting picture and we're going to check that out so first I'm going to start the radar collector application size we're going to see that radar application so the collector is starting on for 9898 on TCP and that's a spring good application and we'll start the tracker application that app is using Neddie as well and we're starting on port 8080 so now let's take an actual look the application so here by default we're using Ruston's profile because we don't have really security yet and we can see that we're seeing radars we're seeing all the planes flying around so I can see that a particular plane has a particular name and same thing for a radar of course when we move the map we'll get the same information updated so one interesting thing thing here is that the first difference with doing that with plain WebSocket is that we have we actually have back pressure control so here with that little widget on the bottom left that's the actual request demand that we're making every second that the JavaScript client is sending to the server so we're asking for 50 new signals every second and that's why we see the airplanes being updated but if I lower that number then at one point the we're getting less and less signals and it's almost crawling to a stop and that's because we're asking for less and less data at one point so we're seeing less updates and it's almost stopping so if I even go over its should be even stopping and when you update that again we should see like big updates and the aircrafts being being updated a bit more so that's the the example of back cursor control let's see how this works in in an actual application so here so we got our application running and I'll show you first the radar collector so the radar collector is a spring bhutesu to rc1 application and we currently have like two interesting I mean one one particularly interesting sorry that's the new one the stream would start on our socket and we only need that to start an our circuit TCP server well of course I have a few other things like string that I'm going to be reactive and so on to get the actual data from our database the other interesting part is the application properties for radar collector because we are here using the required application properties to say I'm going to start at EC and also CAD server on for 9898 and I'm going to use the TCP transport by default so those are the two required things that you need if you want to start an AR circuit application which you can boot then we can take a look at the airport repository so just so you know at application startup we're just storing a bunch of airport data that we have locally and in our data in your database and and we have that repository available in our application so you can find an interval by it could by its code or by its location once we have that the other missing piece piece is the the location information and all the signals that were generating so this is actually the aircraft aircraft signal so that's the raw data that were sent that we're sending so this is the the cosine of an aircraft's its location bearing stuff and so on and capture time so I had a particular instance if you wanna look at the broader picture it's the actual aircraft race and that's where we are doing the probably naive things about calculating GPS coordinates and distance and so on but that's how we're generating the the fig data that looks somewhat realistic in our sample if you're interested in solve it's all there so this class allows you to to calculate distances and to generate that fake data but then we need to produce at some point and we're using the aircraft race generator so that's where one of the other big piece of that application so that generator is a component in our application and you can ask it give me the traces for all the traces for a particular airport so once you get all those traces you can get them updated and you can have signals over time and that's how we're we can draw things in the end but here the other interesting bit is that we are actually storing the traces in a local cache so that whenever you move the map you are not seeing a picture that's totally different we're not generating something that's widely different from what you had so that's what we're that's why we're storing the the trace is locally in a cache at least temporarily so that it doesn't look crazy now the also get specific part is for the radar collector is our controller so like Ross and showed it really looks like your regular controller but this time for message mapping so we're getting our repository in our generator and from there we can expose several services so we can find a radar by its code using our repository and we can turn it into an airport location and send that back the other interesting one will be the message mapping so when you want to listen to a particular radar you can send a message with the actual radar code in the route and we'll map that that code to the variable destination variable here in your controller handler and from there we can find the radar in our pulse tree to get all the information and from that radar will generate the traces for that radar and we'll stream that that information to the client so how does it look from a test perspective so if you look at the radar collector test so this this is a spring boot test class so this is a pretty much a real integration test with actual servers running so here we are actually saying telling spring boots to create the server not on a fixed port but on port on a random port instead of 9898 and so because it'll be random we need that information later in the game so that's why we have the local or socket server port annotation so you can spin we can give you that information back once the server is started and we are also asking spring boot to give us a requester builder so spring what people will do is not not just creating builder for you it will auto configure a lot of things for you it'll auto configure the codex and all the Preferences that you've expressed in your spring application by default in our in with the our circuit server starter we are providing to codex that we think are interesting in your circuit world the first one is Jason uses using Jackson because we think it makes sense especially from server to browser interactions but we also know that behind your firewall in over TCP or whenever you need to be really efficient you probably want to use something like C bar C bar is a binary codec that you can use and it's actually a module of Jackson so it's really from a pure developer perspective if you're used to using Jackson it's just just a switch here when we're calling fine radar by code you can see that we're using the requestor builder were asking for a particular data mind type during the set up framework we're asking for application see war we're connecting over TCP using local send report and this time we can then use the requester so when connected so this returns a mano so it's only when you subscribe that you're actually trying to actively connect so here whenever we're connected we're getting the actual request for back in the flat map and so we're asking give me for that route the information for Datuk their port location and we're getting still a mano and if you're familiar with our reaction tests construct now you can use a step bury fire from react to test that's a nice way to test a Amen or flux you can also use blocking but in that case I've used step step verify if you want to test so I'm testing that the next element that I'm being sent is actually actually that are port then I'm testing the code and the name and I'm verifying that everything is being completed properly so if you look at the data here were actually seeing the airport location for this in the case of streaming aircraft signals so this is not only a request response but a request stream we're getting a stream of information back here it looks a lot like the previous one so still connecting using sea bore and so on but this time we're retrieving the flux because it's potentially an infinite flux we're asking for just the first twenty elements and we're collecting that all that into lists and that's how in this case the test is checking that the generated signals I'll use a particular pattern when it comes to the flight number that it's always a two and then three numbers thing so here as we can see we'll have a list of flight numbers and they look all the same it all matched the pattern that we're expecting so here we're pretty much done with the year aircraft radar so far so we were exposing that information and it's being made available using using our circuit over TCP now we can take a look at the tracker application so the tracker application will will connect to the the collector one to to get information about the flights but this application is a bit different from the collector because this time it's not only it's not just an AR circuit application it's a web real web application so we're using web flux and our socket because we want to have regular web endpoints and we also want to serve static resources and those static resources the actual JavaScript client is a is coded in a different module the flight client module that I won't show today because my JavaScript skills on that great and but just so you know that this is the another probably popular use case that we're seeing and in in that case we are merging the our socket server into the reactionary web flex server so you don't have my two ports or a really complex set up it's all being done for you so this time the properties that we need to declare it's a bit different this time we're asking for the WebSocket transport we're not declaring a particular port because we're using the server port from the web server but here we only have to say I'm making the our socket endpoints available here on that path and that's where the the JavaScript are so gate client will connect from a from that perspective here in the tracker we will collect data from the other service and it really looks like using the requestor and streaming that that data into our application so here is same thing it looks definitely like our tests we will fetch data and and send an airport location return or return flux of signals and so on now on the controller side of things we have something that looks a lot like the radar collector but the main difference is here for example we are collecting all the signals for many radars so for example here we're getting a list of radars and we are streaming many many radars and merging everything into it into a single stream and we were making sure here that when the client is not requesting enough that we're dropping data because we don't need we need to save it and also here the different bit is we don't only have message mapping annotations we can also have regular web controller handlers in the same controller so this is a regular controller Handler and in this case what we're doing is whenever someone sends a request here we're getting the code and we and because whenever something connects a client connects to a streaming service we are making sure to store the requester that a server can use to to talk to the client so we're starting that on the side and then at any point you can send a message here and we'll broadcast to all the connected clients you should go there and all the clients will go to a particular location and we can see how we can do that in a minutes so the question is can we find the find out about the backpressure demand you can but it's it's actually transparent for you if you're using fluxes all along the way from the controller to the database you don't have to deal with it it's it's actually the demand is being from transit translated along the way so that's that's a here in our case that that's how it's done as well um so we will try something here so just to show that we've got so this is so this is our application and I'd like to show you just a couple of things before we end so just to show you that the our circuit CLI still works so here we'll send a request to our to our flight tracker application but we're using just to show you that we can also use specific metadata formats so here we will ask for streaming data for three particular radars on the WebSocket end point and we will get all that data for all the traces for for a few requests and so on the other thing that we can show is actually sending people to JFK so all the connected clients will go to JFK instantly and that's it so that shows you how the server without any other client interaction can you use the requester and be a client of some sort so a requester and send request to a client so it's truly a two-way communication thing all right back to this so we've we've seen so we've seen the basics so this is just a summary but we've seen all that what you need to start so the kind of things you get out of starter spin with starter how to start a TCP server you just need a starter and you need a couple of application properties same thing when it comes to WebSocket server this time you're using web flex in our socket and you also need a different set of properties just to create a different different type of app and as well how we can get a requester automatically configured by spring boot and how you can test things the other important thing is that we are providing more things more ways to customize your our circuit experience in Springwood and that can be pretty useful for extending and adding support for more things so in that case we can use a factory processor so just before connecting you can be there and tweak the connection phase or do something with what's happening with the our socket actual our circuit connection and the protocol itself what future work we will probably do things like improve testing support in spring boots so instead of starting an actual server we could use a local inside the JVM server we could have actuators report and and so on many ideas but we're just getting started let Rob explain about security right now all right we did deliver on our promise of if time for security we will cover it so if there we go all right so we do have a lot to talk about in terms of security but before we go into any of the details about how how we cover security how to do it in spring security I want to kind of give a picture of how it fits into our application so here you can see the flight Becker's gonna connect to the radar collector and as Roslin was mentioning earlier the there's metadata that can be included in the first frame and including the set up frame so here we're doing basic authentication it's not to be confused with HTTP basic because it's it's a different protocol so you encode things differently but it basically you include the username and password in that connection and then once you've set up that connection then spring security kind of decorates it and and we saw earlier in Brian's slides how there's a basically a processor spring security hooks into that processor to wrap the connection and it associates the user that you just established in that connection throughout that entire connection so you pass the credentials one time and then from then on you can use it to make authorization decisions so here you can see this is kind of like the little pipeline that Springs security would build and there's like an authentication at connection that's optionally available depending if you chose to do that or needed to do that and then there's also a possibility of doing authentication per request and then finally you do your authorization decisions and then it after all that passes through the actual existing application will code will execute now there's different times where you might want to do different things on ocation that connection makes sense when you're doing a single client connecting to a server and using that connection just for one user so that for example our JavaScript application will connect to the flight tracker application and it's only going to be one user so we don't need to send on a per request basis and in fact for our radar collect your application just for simplicity and because of our authorization rules it's just a super user that's connecting but let's say that radar collector needed to do something like rate limiting or there was some authorization specific to the users then at that point in time you would need to either send just authentication at request time or you could do both so you could authenticate at connection time do some sort of specific authorization logic based upon the super user to see if the connection is allowed and then for each of the individual exchanges you could do use authentication at request time and then do special special authorization logic on each request so that make sense all right so this is kind of how the flight tracker application will work we'll have the JavaScript application we'll get a JWT from an authorization server and then after that it's going to set it in the setup frame very much like our basic authentication but it's going to do it using bearer authentication metadata and at that point it will set up the flight tracker we'll exchange a public key get the public key to validate it it'll validate it the JWT and then again at connection time it will associate that JWT with the connection and it can be used for authorizations going forward and here's just kind of the big picture of what what everything is going to be doing on the security side we have the JavaScript application as connecting to flight tracker what's you which is using JW T's on a per user basis but again it's a connection per user and then the flight tracker is doing a single connection to radar collector using a superuser for authentication and authorization okay so we've covered kind of the hi big big picture let's see how we can do this with spring security I guess we're already in presentation mode okay so the very first step as you might imagine to adding spring security will be to update our our build file here and we need to do it here and we just need to add Springs to the spring boots starter security and our socket support and then at that point I'm going to just go ahead and run the same test that we saw earlier in Brian's presentation the writer collect your application tests and you're going to see that it's going to fail because access is denied that's all we really need to do to get security up and running and this is kind of what you would expect from spring security at the same thing happens in a web flex application so happens in an hour socket application now to fix our tests we're going to want to be able to know what our password is by default it's going to generate a secure random password but that's not very practical for our testing purposes or for real-life uses usage so we're going to go ahead and open up our application properties for the radar collector and then we can type in a username password now one way you can do it is just type in the password like that and everyone knows plaintext is perfect for passwords right everyone's awake that's great so if you're not aware of it spring boot has a command line utility and you can actually encode passwords using it so here you can see I'm basically just running that command line and it's outputting a beat crypt encoded password so if someone gets ahold of that they're not going to know what the password is so we'll just go ahead and use that instead and now we have our password is still password but now if someone sees this properties file they're not going to have any idea what the actual password is and obviously this is still just a demo but you can do the same thing in your database as well now let's see how we can fix our test - to use a password in them have our flight tracker right okay so now in here we we saw that these tests were failing we're going to have to add we're gonna have to add our credentials to the request and I'm not going to go over the details here but this is integrating with the our socket requester that Rossum spoke about earlier basically we have a username password metadata and that's just the username and password and then we have an encoder and the encoder knows how to encode the username password properly for for us to read and then we modify the builder to leverage both of those now to take advantage of that now all we have to do is just say apply credentials and now if I rerun these same tests will expect that find the fine radar buy code is going to pass and then the other two are going to fail because we only added it to the one test okay makes sense now as you might expect if the if the test if the test actually fails then so will our flight tracker application if it tries to connect to our radar application so we need to fix fix that and the first step to doing that is we need to again update our dependencies so we'll go into our our flight tracker application and then go ahead and add the same dependencies that we had earlier and once we've done that then we can go ahead and go into our radar service and our radar service has much the same setup that we saw earlier in our tests so we're gonna leverage the same piece piece of code there to get our credentials and then we're just going to say apply credentials so now this is setting up that super user that we were talking about earlier and now if we actually ran our application this piece of functionality would actually function but what's not apparent here is that there's also also security being added to our web flex application because there's web flex so you'd require a username password there and then also to the web socket connection from the JavaScript app to the to the to the our socket based code so there's there's a bit extra there now it's important to note that we don't actually need the authorization logic for our web flex portion of the application because basically because there is no authorization necessary for these static resources they're just static HTML pages in JavaScript making requests over over the WebSocket connection and so the only thing we really care about is the the only thing we really care about in terms of authorization is at the website later so we're just going to disable authorization here and you'll see I'm using the new DSL and lambda support within spring Security's configuration will do cover more of that in hello spring security 5-2 if you want to take a look at that but we'll kind of gloss over that for now and the last piece that we need to do in order to get this to function is make it so that we can actually authenticate our user from the JavaScript application to the flight tracker application and in order to do that we could use a username and password as we did earlier but it'll be a lot more interesting as we mentioned using a JWT so let's see how we can do that we'll go ahead and open up our build.gradle again and we'll add a couple of dependencies the the oauth2 client is just going to be for testing purposes so it could be a test dependency but simplicity and moving along will just make it an implementation the resource server is how we're going to validate the JWT and to do that we also need to update our flight tracker application here and we're going to add resource server this issuer URI is just how how we Val find the public key that we need to validate and spring security will discover based on that issue your I and the client could the client based properties are again how we're going to do our testing for that chunk of code now now that we've done that we need to update our tests as well so we're going to go to the flight tracker application tests and we're gonna go ahead and add some code that allows us to allows us to test this easier and all this is doing this is pretty much what we were doing earlier with the username password and the other test but it's a little more advanced because you actually have to get an access token from the server so we're not going to go over the details of that just I'm going to do some hand waving because we're squeezing in security if we have time and well we'll say that's basically getting an access token and it's including the request and then all we need to do now is just say OAuth to login for login all right so now if we run this test it should go ahead and pass and of course it doesn't because it's a demo why would it pass why would it pass but let's see here here we go see actually method is oh I know exactly what we forgot so I tried to skip one section because we're running out of time but that doesn't help matters any okay so what we needed to do is we still need to add to our flight tracker a web flock so our socket security out of the box is defaulted but it doesn't actually use the JWT configuration so what we need to do is we need to do our our socket security config and all this is doing is it's telling it explicitly that we we want to do a JWT based configuration instead of trying to do basic authentication and it it back it basically wasn't creating that username password based authentication because it saw that but it wasn't toggling this configuration here so now you can see we get the green checkmark as we would expect all right from there we still know that there's there's some problems with this code in terms of its it's not actually functional yet and the reason for that is is that the reason for that is is if we changed our profile to be like Brian it's the test is not going to pass so we'll just go ahead and demonstrate that real quick so it's because we're hard coding the login in our controller code to be rawson so we need to be able to figure out how we can actually leverage leverage the information in the authentication object to change how the behavior of the application and so here we're running that test and you'll see that I ran the wrong test because that was the one that worked beforehand it still passes I wanted to prove that that one still passes you see that I know what I'm doing and so this one's going to fail as we as we just discussed and the reason for that is again we've hard-coded hard-coded that behavior so let's go ahead again we need to start off by updating our build file here so in the flight tracker application and the reason for this is most of the support for spring security is actually built into our socket directly but the place that we need to integrate is in spring spring messaging support so spring security also has a hook in there and we'll see how how that actually happens in just a minute so we're going to open up our user profile controller and in here you can see hard-coded user name right only if we have time will we add security so the profile the authentication principle is basically just the current principle of how we've authenticated in this case it happens to be a JWT and to leverage to leverage that we need to get a login and the login is getting from a claim so the JWT has claims and these are just basically assertions about the currently logged in user and it happens to be preferred username and so oops so now if I rerun the same test that we had before it maybe would do both of them if I see here we go so now if I rerun the same tests this is actually going to fail because I wanted to show you one other thing that you have to remember to do and by that I mean I almost forgot to do it might track your application so it basically can't resolve that because it doesn't it doesn't see it doesn't see it doesn't see the argument resolver which is kind of the hook into Springs messaging support for it so that actually has to be configured and then once you've run your test now that you know what not to do you know that that these are will both be green okay so now we're actually able to fluctuate the user based upon the currently logged in user and now if we logged in as as Brian or Ross and we would see their their radars that they have configured now the thing is is all these tests look like they're working and everything looks like hey we're all ready to go and everything's going to work but the reality is is that the JavaScript based application is using a different made it metadata type so we talked about how in you can use composite metadata but the JavaScript application is actually using JSON for its metadata so we need to actually customize how Spring Security's reading in that metadata to get the access token so that it is read from the JavaScript based application and we're going to do it a little bit faster because we were running very short a time it all right and we'll just go over we'll go over the code versus so the first thing that we need to do is there's a way to extract extract data in spring security so you get basically the input as a payload exchange as the payload that Roslyn talked about earlier but you know the mime types as well and then we just basically extract out using this metadata extractor which is built into spring we extract out basically the bearer token there's nothing fancy going on here and then the other thing that we needed to do was we needed to update our configuration here and we basically grabbed that converter and then we create a custom authentication payload interceptor and those are those little gray boxes that we talked about in the diagram earlier and then we make it available as a custom payload interceptor so no longer are we saying JWT default custom default whereas adding that manually and by doing that we now have the ability to extract out the JWT from a different metadata type and the last piece that we really need to do in order for this to work is update our JavaScript and since you would lose respect for me as a security professional if I did any JavaScript coding I stole Brian's JavaScript and and we're going to go ahead and compile it real quick here oops and it's compiled and now I'm going to go ahead and start up these two different applications so we have the radar collector application and then we will start up the flight tracker application so now I just get kicked to kee coke which is our authorization server because it tried to get an access token I'm not already authenticated so it wants once authentication so I'll just go ahead and login as Ross or Bryan and you can see it brings up Bryan's profile and it also brings up his preferred airport and then we'll do another one here and this time we'll login as rawson and this again is just using that custom code where we resolved the current JWT and figured out which user to use and then here it's going to be doing cambridge alright let's see so now we're gonna skip back to the slides very quickly and we've demoed demoed that I want to mention that there are some related talks if you get time but mostly just go ahead and go on there and look at the reactive tag on the schedule and this is our source code for the spring flights application we tried to make it so that if you look at the commit history it'll give you kind of a story of what we told here and there's a security branch don't forget to check that out of course at the last minute but there actually are additional steps for improving security it talks about how to optimize how how to get your principal and how to make it so you aren't dependent on spring security and doing things like methods security and custom authorization those are all in the commits and it's fairly well explained in the commit logs and that's all we have for today other than some questions and so if you have any questions feel free to go ahead and ask [Applause] you
Info
Channel: SpringDeveloper
Views: 13,459
Rating: undefined out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, spring cloud
Id: iSSrZoGtoSE
Channel Id: undefined
Length: 69min 15sec (4155 seconds)
Published: Wed Oct 16 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.