 Hello, my name is Matt Rabel, and I'm a developer advocate at Okta. What I'd like to show you today is how to secure a microservices architecture that was built with Spring Boot, and Spring Security, and Spring Cloud. So let's get started. So the last tutorial, the last screencast I did, showed you how to build a microservices architecture for MicroBrews with Spring Boot. And it's basically just using Spring's Eureka server from Netflix. It's a beer catalog service that has a number of beers in it, and then an edge service which filters out those beers. So at the bottom of that tutorial, there's a link to how to do it with OAuth, or how to secure it with OAuth. So this one is from February 13, 2018, but I just updated this for Spring Boot 2 today, so it should work great. This is a diagram of what it actually looks like, and once you add OAuth 2 in there, we're going to be talking to Okta, but the rest calls are going to go through Spring Security, and Fane and Histrix are already in there from the last tutorial. So you'll start by cloning the aforementioned completed project, but I just did that in last screencast, so I have all the code here, and it's up and running, so I'm going to skip that part. To create a forever-free Okta developer account, you'll go to developer.okta.com and sign up. I actually already have one configured, and if I were to log into it, you could kind of see what's going on, and I'll show you how to create a new application. So it tells you to go to Applications, and then you go to Add Application, you click Web, Next, and then your base could put 8081 in. You can just leave that one, that one doesn't really matter that much. This is the one that matters. So 8081 login, and then you'll just have authorization code, which is a default, and then you'll click Done. I already have one set up, so I'm not going to bother with that, but the one thing that is important is that on your authorization servers, you can add the roles or the groups that the person is in as claims, and those will get translated to Spring Security Authorities. So that's done here. I have one name groups and one name roles, and that's just because I've worked with some applications that expect different names. So in this case, I'm just going to say groups or roles, and just show you what it looks like. You have a regex and .star. So that's how you basically include your roles in an ID token or an access token, and then Spring Security handles the conversion from that role into an actual Spring Security Authority. So the edge service is where we're actually doing the filtering of our data. So if I were to go to localhost 8081, Good Beers, you'll see that I have a list of just Good Beers, and if I went to 8080, this is our beer catalog service, it gives a whole bunch of beers, and we filtered out Budweiser, Coors Light, and PBR because I don't think those are exactly great. So to actually secure the edge service, let's start with that. So I have it all open up in IntelliJ, and you'll need to add two dependencies, Spring Boot Starter Security and OAuth2 Auto Configure. So we'll just go to where there's a nice little blank space here and add those in, and then we'll also add Zool Routes to our application resources. And so right now if you were to go to localhost 8081, Beers, you wouldn't see anything, but if you went to beer catalog service, beers you would. So I'm just kind of shortening those up so you can hit beers directly, and then I'm going to add a path for home so that hits a controller in the beer catalog service that will display and prove that you actually have authenticated and it can read your user information. I'm going to open up application.properties in the edge service and add those routes in there, and then an edge service application. I will add the enable OAuth2 SSO annotation, which basically configures single sign-on with OAuth to my application. And once you add that annotation, spring security expects a number of properties to be configured. So these start with spring or security.oauth2.client and it contains my URL for my tenant, dev158606. If you're not logged into Octa and you're reading this tutorial, it will actually show your Octa domain instead. So put those in my application.properties and then I will need to fix your client ID and your client secret to match what I have in my Octa tenant. So I'll log into my Octa tenant and I'm going to use one of my pre-existing applications. So I have this jubster microservices one already configured. I'll go ahead and go down to the bottom, make sure it's got 8081 slash login in there, copy that client ID and the client secret and that's it, it should be good to go. Oh wait, I need to enable a resource server on the edge service application. So I'm going to actually copy this whole class and what this does is it basically makes it so spring security looks for an authorization header to be passed in and as long as the jot is valid, it will go ahead and allow you to authenticate. At this point the edge service is configured for OAuth and protected by spring security and the next step is adding spring security OAuth to the beer catalog service. So in the beer catalog services, palm.xml, you'll need to add the same dependencies you added to the edge service as well as one for time leaf and you'll add the same properties and application properties. And so one way to do this is actually you don't have to put all these properties in your application properties. You can set them as environment variables and this is definitely recommended for production because you don't really want your client secret to be stored in your GitHub repo or whatever source control system you're using. You usually want secrets to be hidden. So in, I have a file, octa.env that you can see in this file I actually override those properties and set them based on information that I have. So this will allow you to actually have empty application properties without defining OAuth properties and if you were to go to production this is what you would use, this is what we would recommend. But for the meantime it's kind of easier just to see what they look like I will copy the ones from my edge service and put them in beer catalog service. I'm going to create a home controller in this same project that basically displays the user's information from the principal and the reason I'm doing that is to show you that that jot that's propagated from the edge service down to the beer catalog service does have the user's information in it and you can see that that propagation is working. So this controller here you can see it just reads from the principal and takes all those details and stuffs them in a map and then returns a user object. So to display that I'll create a home.html template that basically lists through all the various attributes that are in a user object or in that OAuth to authentication principle and then this project will also need a resource server to look for that authorization header and at this point you still need to configure the various services to be OAuth enabled per se. So for the feign client we need to create a interceptor a request interceptor that will add the authorization header to that request. So here's the code that you can use for that create the user feign client interceptor in the same packages edge service application and you can see how it just grabs the token from the security context and stuffs that and the request template header grabbing the token value and you'll need to register that interceptor as a bean in the edge service application or in any configuration class that you have in your project and you'll also need to add two properties to your application properties to basically enable his tricks and allow it to use the security context. So that's the feign.histrix.enabled equals true and histrix.shared security context equals true. So you just put those at the bottom here and now we can verify our edge service and our beer catalog service are communicating with each other so restart that beer catalog service and restart the edge service and once everything's restarted we could go to 8081 good beers and we should be redirected to octa see a login page and be prompted for our credentials so we'll click on this link and open up that good beers endpoint and looks like we're already logged in so I'm going to open an incognito window and go ahead and hit 8081 good beers and you'll see we're redirected to octa type in our credentials and that works we're still getting an empty array list I think that's because the beer catalog service hasn't quite registered with Eureka so let's try the beers endpoint okay so that's working and good beers one more time there we go so now it's pulling those in and we're authenticated and everything's working so that's great now let's see if that home endpoint works we're getting a 500 error there so that's kind of strange see what the stack trace says it says it's in the home controller line 18 if we navigate to that class what did I forget oh it's right in the tutorial there don't basically it's working with the feign interceptor right that good beers is working talks down to that beer client but for zool we're not propagating the access token so you need spring cloud security as a dependency in your palm dot xml to do that so this is in the edge service you'll paste that in there for a great spring cloud security and this will propagate that jot and then restart it and restart the beer catalog service and now you can go to 8081 slash home so everything's up and running and voila now we're seeing the roles that are in that ID token as well as all the other information the logout button doesn't work but that is an issue that I've talked to the spring team about and haven't figured out a solution yet so the downstream service actually 8080 is not protected at this point so if I'm going to go to localhost 8080 slash beers you'll see that it doesn't make me login so for home it gives that error for beers it lets me through so this is a different behavior in spring boot 1.5 versus 2.0 and 1.5 actuator would register its own web security configure and with 2.0 actuators like disabled by default so you can configure your actuator endpoint so they're exposed and then create a security config to protect them and that will allow you to restore the behavior that you had in spring boot 1.5 another way to do it is just by using enable OAuth 2.0 SSO so if you put that on the beer catalog service application it will redirect to octa and have that similar functionality so I'm going to put the management endpoints web exposure include into my application dot properties and then I'll create this security config that basically says hey you have to have an admin role to view those endpoints so now I can restart the beer catalog service application and it will be protected with basic authentication so now if we hit localhost slash just 8080 you'll see now it's protected in the last tutorial I showed you how to create an angular UI to talk to this beer service this good beer service and show those now what we'll do is go ahead and integrate octa sign in widget to the angular client and this will basically allow you to authenticate on the client in the single page application and then pass that access token to the server and get the list of beers that way so you can take that same client that you registered and just make sure it has implicit grant type allowed and then this will all work so I'm going to go ahead and go into the client service here and add the octa sign in widget using npm install let's see it uses octa sign in widget version 290 and then in the styles.css we'll add the css files needed for the sign in widget and then I'll create an octa.service.ts that configures the widget specifies the base URL specifies the client ID and the authorization parameters for instance the token types that it wants the scopes that it needs as well as methods to get the widget itself and the ID and the access token so once you create a service this is using angular 5 you'll need to register it in the app module with angular 6 things changed a bit so you don't need to do that as much anymore I'm going to go ahead and grab the client ID and put that right here then register it in appmodule.ts doesn't seem to be resolving that import so I'll just paste it in there and then in the beer service we'll need to actually grab the access token from that octa.service and put it into an authorization header you could also use an HTTP interceptor to do this so it would basically configure it for all your HTTP calls but I think this is a little more straightforward and just easier to understand in the beginning and then we'll need to make that octa.service a dependency in our constructor and notice that headers is immutable so you can't just do headers.append you actually have to reassign it to headers and then this is a mistake I always make so you add it to the HTTP get so if you don't do that then it won't work and you'll be stuck trying to figure out why, why doesn't it work and then we can modify the app.component.html to have a div that can basically render that sign-in widget and to show the user's information after they're signed in and basically say hello how are you and if you want to log out here you go log out here and in the app.component.ts you'll need to make some changes to basically detect if the user's logged in or not so we'll put those variables in there and then the constructor has that octa.service changeDetectorRef is used to basically detect when some state has changed outside of Angular and you trigger that until Angular hey you should go and check everything is tracked again so that's where this octa.sign-in container matches what's in the HTML the getUserMethod we still need to add so copy that from our tutorial and we're just going to grab the claims out of the ID token and create a user with that using the name email and username and then when this app.component initializes we want to see if the user's actually signed in so we'll implements on init and it'll use the widget to go and see if there's an active session and then to log out we'll call the widgets signout method and then re-show the form so this changeDetectorRef is also needed in the beerList component to basically trigger it to go and fetch the user's again after you've authenticated so if you open up beerList component you'll add a changeDetectorRef import that and then right after you set the GIFI URL go ahead and add it in there and now we can verify the authentication works so start up the client using npm start or yarn start which I really like localhost4200 check for any consular since it doesn't render and then try and incognito window that usually works so now we're seeing the form and we could type in some valid credentials and we're actually logged in and we see part of our beerList let's try that again nope oh there's an htb error response there you see so the preflight is invalid so it's basically saying that hey it doesn't recognize our core's header so we need to go into our edge service this is actually a problem that you see with spring security once you've added that in it doesn't honor those cross origin annotations and you actually have to add a filter in that has a higher order precedence and will basically allow that origin request to happen so if we look down here there's a filter registration being that configures things and so I'm just gonna basically allow all origins but you could also change it to just allow localhost4200 so make sure you get the servlet based stuff since we're not doing web flux here and import class make sure it's from spring and then I'll add a suppressed warnings because that's the easy thing to do and set it to unchecked now that warning will go away and so now we can restart the edge service application and we should see our list of beers so localhost4200 log in with valid credentials and it looks like it's working on the right I mean it made some requests try refreshing there we go so there you have it you've built a robust microservices architecture you've secured it with spring security OAuth very nice I hope you've enjoyed this tutorial of developing apps with spring boot and spring cloud and spring OAuth you could also deploy this to cloud foundry I've got a deploy.sh script that automates everything you will need to go and adjust your octa app to have a new login redirect URI that points to your production URL and then everything will work the source code for this tutorial is on github under spring boot microservices example it's in the OAuth branch so make sure and check out that branch so if you're interested in learning more about the future of spring security Joe Granja did a great talk at spring one last year in 2017 shows you how to basically login with OAuth 2.0 with spring security and that's very similar to what you saw here it's just the configuration properties are a little different I also wrote a couple tutorials on doing the same thing with jhipster and ionic for jhipster so I'd invite you to check that out and you can learn more about octa and its apis at developer.octa.com thanks for listening and I hope you have a wonderful day