Spring Security CORS: How to configure CORS in Spring Boot & Spring Security

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this tutorial you're going to learn how to configure cores in your spring boot application course is an HTTP header based mechanism that allows you to specify in a flexible way what cross domain requests should be authorized you're going to learn how to configure cores in Spring boot at a controller a method and at a global level we'll also discuss what you need to do to configure scores when you bring security into your application welcome back everyone my name is Dan Vega and I'm a spring developer advocate for VMware I want to jump right in today but as always all the resources that we're going to discuss and the GitHub repo for all the code we're going to walk through today is in the description below what are we waiting for let's write some code we are going to get started with this demo like we do with everyone by heading over to start.spring.io we're going to be creating a maven project using Java we'll use Java 17. I'll film some metadata here you can fill in yours I'm going to say Dev dot danvega is the group The artifact is going to be core demo so the only dependency that we'll need for right now is spring web again we will bring in security bits in a little bit to talk about the security configuration but I want to start with just the web application so we can take a look at core's configuration before we get to the security step so when you have that ready go ahead and click on that generate tab button down below you'll download a zip and you can go ahead and open it up in your favorite IDE or text editor I will go ahead and open it up in mine IntelliJ alright so I'm a big fan of coffee I've been using coffee domain in my tutorials lately we're going to kind of continue with that today so in my source main Java I'm going to create a new package we'll go ahead and call this model and in here we're going to create a new class we'll call this coffee and we're going to create a record type here and we're using Java 17 so we can go ahead and take advantage of that I'm going to create an integer ID a string name and a string actually we're going to have this as a size of size so this will be an enum we'll go ahead and create an enum size inside of model and in here we'll have a few values short tall Grande and venti so those are my sizes now I have my model next thing I want to do is I want to go ahead and create a coffee controller so let's go ahead and create a new oh we didn't get that in the main package that will cause us a problem later so let's make sure that's there let's create a new package we'll call this controller and inside a controller we'll create a new Java class and we'll call this coffee controller again that's by convention you don't need to call it that but you'll see that often in Spring applications just using that Convention of the controller suffix so I'm going to go ahead and Mark this as a rest controller this just says hey I can go ahead and accept requests and return responses I'm going to go ahead and set a request mapping of Slash API slash coffee don't mind those hints that are coming up those little gray hints as I start to type that's GitHub copilot I can go ahead and turn it off here if I want but I like showing off sometimes so I'll leave it on for today so we need to go ahead and create a list of coffees and we need to uh I'm gonna paste some code in here so we have to watch me type this so I have a private list of coffees uh we'll call this coffee list this will be arraylist and we'll just add three different coffees to there so we had um an ID of one two three we have our names here Americano latte macchiato Grande vente and Tall so now that we have some coffees here again this is just for the demo at some point you would extract this out into a service or a repository talk to a database Etc we're just going to kind of keep this pretty simple for this demo so I'm going to set a git mapping and what we're going to do here is return all of those coffees so I'm going to say coffee we'll call this find all and want to return our coffee list so that will be our find all and then we'll also have a delete mapping so public void delete and if you wanted to delete one say by a specific ID we'll say integer ID and then we can say coffee list uh yeah that actually looks pretty good thank you copilot for helping me out there so now I just want to go ahead and run this application so if we go ahead and run it we can say run here let's run our application and we should see no errors now we can go ahead and head back over to the browser and if we go to localhost 8080 slash API slash coffee we should see the list of three coffees now you can also do this by heading over to some tool like Postman and in post manual kind of get those coffees back as well so to explain chorus a little bit further I've copied in a new application a front-end application into Source Main in a folder called frontend you can find it in the GitHub repository that is in the description below but I just want to walk through this real quick I didn't want to take the time to go ahead and type this out together it would have just kind of added a whole bunch of fluff to the video so this is a View application that is using Veet so Veet is this really great tool that you can use to build a whole bunch of different projects view being one of them so in here we have our Veet project we have our package.json you can see it just includes V we'll go ahead and cancel that for now it includes View and then it has Veet for the dev dependencies inside of source we have an app.view and this is the only component that we're using right here and we'll talk about this code a little bit more I guess so what happens is um we have a list of coffees when this component is mounted we'll use the fetch API to reach out to localhost 8080 slash API coffee that is the one that we just used before we don't really care about this uh authorization header right now in fact we can go ahead and comment that out that will make more sense once we get into kind of the security stuff so I can actually just get rid of that all together so once we reach out to that then we're going to get some response back we're going to turn that response into Json then we'll take that data that we get back and we'll set the copies.value equal to the data and then we'll simply just iterate over that list and display the name of the coffee a very simple front-end app but we need this app to kind of talk about the issue of cores so what I'm going to do is I'm just going to open up a terminal here and we'll go ahead and move into Source oops sorry about that main front end and what we need to do is just npm install all right and then I also want to make sure my application is still running it was not so it was stopped so I need this running first because I'm going to call localhost 8080 so we want to make sure that this is running and it is so if we head back to the terminal now what we can do is go ahead and npm run Dev and it is now running on localhost 5173 so let's go ahead and open that up in a browser all right and as you can see we have this coffee list but we don't have our list of coffees so if we go ahead and inspect the page head over to the council you see that we're going to get some errors and I'm sure this is probably if you've done any kind of client server front end back end you've probably seen this error before access to fetch localhost 8080 slash API coffee from a different origin has been blocked by the course policy so this is saying hey this is specifically a cores issue you are not allowed to access this API from this origin because those are two different Origins localhost 5173 localhost 8080 even though they're the same domain localhost they are in different ports so this is where cores will kick in and say nope you're not allowed to do that so if you're unfamiliar with cores I thought I'd go ahead and share this link with you as well over on the Mozilla Network this is a really great document that goes through what cross-origin resource sharing is basically it's a header based mechanism that allows a server to indicate that any Origins whether it's the domain scheme Port other than its own from which a browser should be permitted allowed to load those resources right so this is cores relies on a mechanism which browsers make a pre-flight request so this is like a quick request saying hey do I have access to this and then in this case the answer was no so if we go back to the browser and we refresh local CDE that still works again same origin so it doesn't matter but as soon as you cross Origins now we need a way in our application to say that we are going to permit localhost 5173 or any or all Origins to go ahead and access this resource so with that little background on cores I think we can talk about how we can do this this in our spring application now all right so I'm going to go back into my Java application here and I'm going to open the coffee controller and there's an annotation that we can use to go ahead and configure cores and that is the cross origin annotation so this can be marked at the class level or at a method level so let's take a look at it at the class level so we're going to say cross origin and then you see we're getting some hints there but I'm not going to add any more configuration to it I'm just going to save this and head back over to the browser actually we need to go ahead and restart this application for those effects that take place so let's restart our spring application go back to the browser and refresh this and as you can see no more cores error right we are not getting a course there we are able to list out those three different coffees and that's because at the class level we said anything in this class I want you to go ahead and make available to anyone calling this now as we saw let's go ahead and look into this annotation a little bit further and we can see some deprecated stuff up here but we can also see that there is a so the value for uh is an alias for origin so if you don't type in origin equals the default string that you put inside of that annotation will be for Origins but Origins is a list of Origins for which cross-origin requests are allowed so if we didn't want to allow just anybody to hit this we can go ahead and say Origins is equal to and then the domain slash Port of where we want to allow access to this now I know I'm not running on 3000 right now but I want to show this right so if I go ahead and refresh this restart the spring application head back to the browser now we're going to get that cross origin error again because we are on 51.73 not 3 000. so if we go ahead and change this to the specific one that we want to allow so we want to open up 51.73 go ahead and save this and restart this we can go ahead and refresh this and that will now work so so far it's so good now you can add multiple origins in there if you want again I probably unless you want it to be open to the public I would be very specific maybe there's just a set of services on your application that are allowed to access it go ahead and lock it down to those now if we don't want to set it here at the class which gives a basic blanket statement for everything that's in this class what if we want it to get a little bit more granular what if we wanted to say that like hey anybody can go ahead and access this find all but maybe we have an internal app for admin stuff like deleting or updating or creating we can get a little bit more granular at the method level so let's go ahead and say cross origin so we're basically saying anybody can get to this find all method but hey cross origin we want to go ahead and say that we do have a local host 3000 app that is allowed to access this this particular delete method so if we were to go ahead and restart this and go back to our browser now we can at least get to that specific git mapping that allows us to list all of them so this is a way that we can do it there I'm going to go ahead and get rid of these and what I want to talk about is you know this is fine for this one controller because we had one controller now when we get into large applications you may not want to have to like sit here and you know add these different annotations to each controller class or each method that you're trying to configure so the next option that we have is to create a global configuration all right so to create my configuration I'm going to go in here and create a new package we'll call this config and I'm going to create a new class in here called Web MVC config and we're going to implement the web MVC configure look it already added a whole bunch of code for me which is nice and so what this will allow us to do is we can override a specific method called add course mapping and that brings in the course registry and then we can allow we can set mappings for specific things so in my case maybe I want to do this for everything but maybe I want to just do it 4 API slash coffee I want to go ahead and allow 51.73 and you can set the allowed methods you can also do some other things in here like we'll get into like allowed headers so if you're passing specific headers like authorization and then allow credentials so we don't need the credentials now but that should give us everything we need so we're setting the allowed Origins we're setting the allowed methods let's just say just get we can say head um we don't even need those so let's just say uh get is what we're allowing for now okay so that will give us the kind of global configuration so we can come in and add all kinds of mappings here for different paths for different Origins Etc so this gives us one place that we can set up this so now that in place we don't have any Quest origin annotations on our methods or our coffee controller so what we want to do is we want to go ahead and see if oops and I realized I just forgot the configuration annotation which we'll need so this gets picked up if not this configuration would never get picked up so if we head back over to the browser and refresh this we can now see our three coffees so so far it's so good uh you may have known a lot of this was available but I thought just a quick refresher on course configuration before we jump into the security bits all right so what we're going to do is go into our Palm here again we didn't add these security bits at the beginning I'll go ahead and add that now so we'll just say spring boots starter security from springframework.boot we'll save that we'll reload Maven so that picks up those changes downloads that dependencies and we are ready to go so I'm going to come into my config package I'm going to create a new Java class we'll call this security config if you've been following me along lately in my tutorials you'll probably have seen me done do this a lot lately we're going to start with at configuration at enable web security we used to extend a abstract class called Web security configure adapter we don't do that anymore we've moved to a more component based model so here we're going to create our users and our security configuration so I'm going to go ahead and quickly add a user so you don't have to watch me type that out that just gives me an in-memory user used for testing do not do this in production and now I'm going to create a new Bean of type security filter chain and we'll call the security filter chain this will take take in our HTTP security we'll call this HTTP and then ultimately this is going to return http.build this will also throw an exception and here's where we go in and customize our security so we might have something for authorized requests so we might say something like go ahead and lock down any request and make sure that you are an authenticated user if you are viewing that so that will give us exactly what we need there we may use something like HTTP basic here and we'll just use the with defaults and that is what a normal configuration will look like so what I want to do is stop and restart this we still have our web MVC config in place so this should allow us to hit the application from our front-end applications if we go ahead and refresh this hmm something is happening here it is no longer working so access to fetch at our locals 8080 is not available on 51.73 so the reason this is happening and I'll leave the link to the documentation in the description below is it says here spring framework provides first class support for Cores but cores must be processed before the Spring Security because of the pre-flight request that we talked about will not contain any cookies if the request does not contain any cookies and spring Securities first the request will determine that the user is not authenticated since there are no cookies and reject it so it this art this kind of documentation just goes into exactly what we're going to cover here but we'll start with the cores and using the defaults so the first thing we need to do is we need to come in here and we need to say cores and what we got to say is with defaults and what we're seeing there with defaults is this with defaults now saying okay I'm going to by default use a bean by the name of course configuration source so we need a bean of this type of of this name to go ahead and set up cores configuration so now here in our security configuration I'll create a new Bean this will be cores configuration source and we'll name the being the same so by default unless we come in here and give it a specific name it's going to use the method name and that's the exact one that we're looking for so what I'm going to do is just paste in some configuration here and we'll talk about it so this is creating a course configuration so new course configuration it's setting the allowed Origins so just like we did before we're setting the allowed Origins this can be a list so we're just passing in one for now this can also have methods so we're saying go ahead and set those methods as well you can also go ahead and set allowed headers so if we wanted to pass in a header like we do in our front end we can go ahead and set that authorization header to match that username and password so then we're going to say the URL this is coming from web cores and again we saw a reactive option in there as well this will work in the reactive world so we're setting the configuration for um slash star star and then passing in our configuration so all in all even if this looks a little confusing this is just another way to configure cores when you're using Spring Security this is the approach that you need to take so what I'm going to do is come in here and basically say I I don't even need this class anymore so go ahead and get rid of it that's okay we don't need it this is what I want to use and then so I don't know if I can go ahead and back this change out yeah so all right sorry about that I had a quick typo here in my unmounted hook just going to go ahead and rerun this application here and our back end is running and if we run this again uh we should be able to see a list of coffee names so cool uh just to kind of recap we took a look at different ways that we can configure cores we can do this a couple different ways so when we're talking about just configuring it on the back end we can go ahead and work on the controller so we can go ahead and add our cross origin annotation at the controller level at the method level we can even create a configuration which we saw earlier that MVC config to do Global configuration across multiple controllers for all the different things Origins headers Etc when we add Spring Security in there and we talk about using our Spring Security config we need to add this dot cores this will say of course when we say customizer with defaults we're saying Hey by default we are going to look for a bean of name course configuration source so I created a bean with that name and I set up my configuration I set up my allowed Origins my methods my headers Etc so I really hope you enjoyed this this was kind of a walk down in how to configure cores what it is why we need to worry about it how we deal with it when we're involving Security in our application so if you did enjoy this do me a big favor friends go ahead and leave me a thumbs up hit that subscribe button and as always happy coding here we go [Music]
Info
Channel: Dan Vega
Views: 8,618
Rating: undefined out of 5
Keywords: dan vega, java, cors access control allow origin, cross-origin resource sharing with spring security, cross origin resource sharing, enable cors in spring boot, @crossorigin spring boot, @crossorigin, spring boot, spring framework cors, spring security, spring boot security
Id: HRwlT_etr60
Channel Id: undefined
Length: 22min 47sec (1367 seconds)
Published: Tue Sep 27 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.