 I grabbed the mic. I assume that was the right one. That's just for the video though, right? I need to use the podium mic for the room. Oh, it should work. Oh, it should. Oh yeah, I hear it now. Let's test it. Make it out of the speakers. Yeah, feel free. Yeah, that'd be great. It's going to be supposed to be 10 minutes of questions at the end? Or... Okay. Actually, you know, I'm watching... I think I have a clock on my powerpoint. I'll be fine. Yeah, it's fine. So this is Aaron, and he's going to talk about authentication. So get ready for all that. And at the end, if you have questions, there'll be time for questions. So hold on to this. Yeah, thanks. I hope everyone's doing okay. This is late in the day. You know, it's been a lot of sessions. So yeah, I'm Aaron Perrecchi, AaronPK on Twitter, AaronPK.com on the Internet. I'm a developer advocate at Okta. And we have a Twitter account as well. Do a lot of blog posts about OAuth and authentication and things there. I also maintain OAuth.net, which if you're familiar with, if you've ever encountered OAuth, you've probably landed on that site at some point. It's publicly editable as well. It's up on GitHub, so if you ever have any things you want to add to it, change, feel free to send a pull request. I also wrote a book about OAuth called OAuth2 Simplified, trying to make it easier to understand the people who are getting into that. But I'm here to talk about something vaguely related to OAuth this time. Starting with a little story about a avocado company. And this is the website for the company, Avocado.lol. It's a real website. And this theoretical company doesn't really matter what they do. Let's say they make custom Avocados, custom printed Legos and Avocados. And they start out launching just a static website for their company on Avocado.lol. And as they start hiring people and growing, they add a private workspace for managing brand assets and things like that for the employees of the company. But they don't want that to be public on the internet, so instead they stick it behind a private network. It's the easiest way to do access control. Make it accessible to the internet. Then they realize that a bunch of people are working from home and don't have access to the private network. So they move it back out to the internet and then add a login form and a user database. So as they grow, they build they start adding more internal sub-domains, like a stats server showing like Munion for server monitoring. Munion just publishes all of its files as static HTML and static assets. So in order to protect those, there's no database you can put in front of it. There's no login, so they just use an htpassword file. And then they set up a continuous integration server. And that one happens to have GitHub off built in. So now at this point, as the company's been growing, they have three places in users. So when a new person joins or when someone leaves they have to add the wiki account. They have to add them to the htpassword file. They have to add the person to the GitHub organization. So obviously that's not ideal. So they go looking for new solutions and find some sort of like single sign on thing and set up a new server for that with its own user database and try to tie these all in together. So they manage to find a wiki plugin that handles single sign on with that server. They manage to find a plugin for the CI system but then what do they do with this pile of HTML files? Somehow integrating that with it. There's got to be a better way to do this. So thankfully there is this little cool thing that's already part of Nginx called the author quest module. And I was pretty surprised to see that this is part of Nginx but it's not there by default. You do have to add a flag when you're compiling Nginx to enable it. So what this ends up doing though is this basically sits between your, sits between all your servers and any time a request comes in. So public requests of this site go through like normal. But if you've configured the author quest module for these subdomains, before a request goes and hits the subdomain, it first makes a sub request out to something else that you define. And depending on what HTTP code that server returns, it will either allow or deny the request down to the back end. It's not too hard to configure but the docs on Nginx are a little bit rough around the editors. So we'll walk through some of that. This is basically the bare minimum you need in Nginx to set it up. So first you tell it to enable this sub request. That's the location that Nginx will send the request to. And then you handle that location in your Nginx config and proxy it back to some other system that's going to decide whether or not the user's allowed to see it. We also don't care about the request body so we just have it stripping the body. That makes this request go faster because it's not also passing the whole body through. So you have this new thing, we're going to call it login.avocado.lol, and that thing is responsible for authenticating users and getting them to log in. And that way all the user management is contained in that one piece. So how does that actually authenticate people? The author request module doesn't have any concept of what is required to authenticate people. It just says if this endpoint returns 200 it will let the request through. So there's this cool little project called lasso. And this is essentially a little microservice that handles authenticating users. It's written in Go so it's very easy to deploy. It has configurable providers so you can swap out you can choose how you want to actually authenticate people, whether that's via GitHub users or a custom OAuth server. You get to decide how long the sessions last so you can decide whether people are logged in for just two hours and have to authenticate or if you want to just set a cookie to last ten years then they never have to log in again. This microservice is the one that is going to be handling that post request or the sub request from Nginx and it will return either 200 or 401. And the way that this remembers whether people are logged in is by setting a cookie which is a jot, which is a self encoded token so there's no database, no storage requirements and it's very fast to validate it. So in order to set this up we're going to take our normal stats.avocato.ll server block and we're going to add that author request line to it. That's telling it to send that sub request to that path. That path is going to be handled by this middle chunk which is basically proxy that request back to the go microservice which is listening on localhost port 9090. And then that will, when the user is not logged in that's going to return 401. So then over here we have it say okay when that service returns 401 we're going to do this which is redirecting to that service to tell that service to log the user in. So we'll log through this in a minute and then we need a new server block for actually configuring the host name login.avocato.ll and that's basically just proxying to the go microservice as well. So that it has a public host name so that you can visit it in a browser. So with this setup you can configure to actually authenticate users via a number of different ways depending on what you're trying to do. It has built in support for github. It has Google OAuth support. You can even point it at your own WordPress blog to use your own WordPress users as your user store. And you can point it at a custom OAuth server as well. So this ends up working like this. When this is all set up someone visits stats.avocato.ll and Ginex says is there a cookie? Or it says I'm going to ask the go microservice if the user is logged in. There's no cookie so that service returns 401 which redirects the user to the login page. This is just a thing that starts the OAuth request with whatever provider you've got set up. In this case Google. So this is the first thing the user sees. Those two redirects happen almost instantly. And then the user sees we're trying to log in on Google and then after they click that account they get redirected back to the login page which issues the cookie and then redirects back to the stats page and now they have a cookie so they're authenticated. So we're going to walk through that again in a different form. So it starts out with the first request from a new user with no cookie from the browser to Ginex. Ginex passes that request on to lasso. Lasso says oh there's no cookie here so return 401. Ginex returns 302 back to the browser from that complete block we set up. At that point the browser then talks to lasso directly and says I'm starting the login process please. Lasso says wait, go to Google to log in. So then the browser does a normal Google off flow which is go fetch, go show the prompt at Google. Google says do you all want to continue logging into this app? User clicks yes and then it sends back a 302 back to the login page with a code in the query string. So the browser fetches the login page with a code in the query string behind the scenes lasso now takes that code and gets an access token from Google and finds the user name of the person who logged in or the email address of who logged in and then sets the cookie and then redirects back into the stats page and now that first request happens again but the same with the cookie and because the cookie is there lasso says yes this user is logged in, returns 200 and then it can return the page. The really cool part though is that this happens so fast that the user never even really knows that there was anything in the middle they never see anything from lasso it's completely invisible. So there's a couple of different ways you can configure lasso depending on what you're trying to do. You can, if you're using Google for example, anybody can have a Google account so you can limit it to the domain name of the service so you can say I'm only going to allow people with an email address ending in albacar.ll to be able to actually see the content behind it. The other way is if you're using a custom OAuth server then if the user can log in at all then they're authorized. So basically you don't need to then write those specific accounts or domains you just say if the user can log in at the server that means they can access the back end. The other mode it has is if you want like a read only version of a site to be public with no authentication you can then have lasso pass the request through or acknowledge even without a cookie say it's okay. But then if you log in the back end will get the name of the user who's logged in so you can give them additional privileges if they're logged in so you can do like read only public with login to edit. So lasso is configured using a YAML file so it's pretty easy. This is an example of Google so we're going to say require every request to be authenticated so this is not a publicly accessible content on the back end. We are going to only allow users at the domains below and they have to have an email address at that domain and then you go and you make a Google app and you plug in the client ID and the client secret here. The other mode you can do is a custom OAuth or OpenID Connect server so this is an example of again require authentication of request but allow all users to do it to true because if they have an account at your customer server it's assumed that they're part of your company and that they can log in and then for this case you need to actually go and provide the URLs to your OpenID Connect server. Another option is if you have a WordPress blog you can go and install the plugin to enable it as an OAuth server and then you provide your WordPress OAuth URL here and this one will again require authentication of request that's basically just the WordPress OAuth server config and now when the user hits that they'll end up on WordPress to authenticate so that was like this for the stats page hits the login page then you end up on WordPress and it says the app is trying to assign you into this website redirects back to the login URL which redirects back to the stats in the login. The last example is GitHub where you can go to GitHub make a with this one you might use this for the public access mode like public wiki where even if you're not logged in it still shows you the content it's just that if you log in you get additional privileges it's true so anybody with a GitHub account can log in and then you go into GitHub and you make an OAuth app and plug in the client in the client secret and so that would look like unauthenticated you would actually see something in a login link and if you click the login link you redirect to the login page which redirects to GitHub and shows you the prompt redirects you back and then you're logged in. So how do you know who logged in? There's another one more trick for this which is in the engine xconfig lasso will actually set an HTTP header in that proxy request and that sub request that has the email address of the person who logged in. So it's made available as this x lasso user header using this author request set thing which is part of that plugin you can set it to a variable available here so you can then use it in either your FastCGI or proxy configuration block and set it as an HTTP header. So at this point we're basically passing that from the lasso backend all the way up into an HTTP header that makes it into your app. So like in PHP it just shows up as a server remote user and you can use that to tell whether the person is logged in or not and who they are. So this lasso is basically responsible for starting the OAuth flow with the provider that you've configured verifying that callback that they've actually logged in verifying who they are, creating a jot and returning it in the cookie header and then verifying that cookie on each request. So if you're not familiar with that it's a self encoded token there's three parts to this. This just ends up as one long string they're separated by periods. The first part is the header, middle part is the payload which actually has the data you're going to use in it and then the bottom part is the signature. If you base 64 the top two you'll see that they're just JSON strings in them. The first one just tells it what algorithm was used to create the signature and then the middle one middle chunk has the data in it. So in this case this is what lasso uses to say here is the date that this jot expires and here is the email address of the person who signed in. This is signed with the secret key that only lasso knows. So trying to modify those will cause the signature to fail. The other cool thing is that this means that lasso doesn't need to store this in a database and there's no lookups when it's trying to verify the cookie. It can be validated extremely quickly because it's just pretty simple math. There's no database lookup or anything. So with that in place you can now start adding more things to your back end all protected by the same log in at the front no matter what they are. So whether it's a an app that has the concept of user accounts or just a pile of HTML and you can just slap this in front of anything. This is great. This lets you have one place to manage access to all these back end tools. Each user has their own login instead of setting one main password in your htpassword file and sharing it around the office. It can protect any app even if that app doesn't support authentication itself which is pretty cool. So getting started. If you're not familiar with I wasn't familiar with running go projects when I first started using this but it's actually not that hard. Once you have it installed you just run this. You go into that folder you run build and then it builds a binary you need to set up the config file so it doesn't even have a config file on the project and then you run it and it starts listening on whatever port you've configured and you're often running. So yeah that's the end of that thanks for listening. The slides from this talk are actually at avocado.lol and there's actually a demo of this working as well. If you go to avocado.lol there's a link to the fake stats page which then you can actually try to log in and it'll get you to log in using github. So yeah thanks. I'm happy to answer questions since we have a few more minutes. Do you know if lasso Oh good idea. Do you know if lasso allows multiple authenticators somehow? So instead of google or github you can configure google and github No it only supports one. What would be the use case for supporting multiple? Make your own choice like public facing make your own choice google or facebook. I guess it's a pretty common pattern for public stuff. No because I guess it wasn't designed for public facing web pages. It's definitely meant for protecting internal tools not for just general user authentication but that's kind of a cool idea. I could see extending it for that. I had a couple of questions. One is that you given some great points of like the pros to using this. I'm really excited about it. But I was wondering what sort of I guess cons or challenges of using it especially because you mentioned that is secure but kind of like what type of capacity of security does it have. And then also is this similar concept of how a lot of other sites and organizations and companies will have the option for people to like sign in through their google or facebook account. Is it kind of similar in that sense? So I guess I'll start with the second question. Typically when you're seeing like someone's signing with google or facebook button they've like that's part of the app that they've written and it's usually done as just built into whatever the thing that you're logging into. Whereas this is like sticking it out in front so the thing behind it doesn't even know that it was talking to facebook or github. So it's kind of a different approach but it ends up being similar in the end result. As far as the security question the um is around running this. There were a couple of things that tripped me up a little bit when I first started using this. One it does require that this lasso service is running. So that means that like make sure that you set it up with the process monitoring thing that's going to restart it if it ever crashes, that kind of thing. Like you would run any other service. And the sorry what was the what else were you asking about security of it? Just type of like the cons of using this in comparison to other objects. So when lasso issues a cookie that cookie doesn't expire until the lifetime that you've set so one of the things that this does not have right now is the ability to preemptively revoke tokens. So let's say you've set up like a one year cookie just so that your employees never have to log in again after they log in once. If someone gets fired and you need to actually move their account you kind of have to like do it pretty manually. Go in and like adjust, change the Jot secret and everybody gets logged out that kind of thing. It's like it doesn't have very thorough user management tools built into it right now. So that's a potential like thing to be aware of. Thank you. That was awesome. So in the partially public model where you want to let some people in, is engine set up so that it's still sending that sub request every time to lasso and then if so how do you tell lasso which part to actually force authentication on because I didn't see that? Oh sure. I kind of glossed over that part of it. So every once this is configured every single request it ends up sending the sub request to lasso and whatever headers are in the request gets sent. So lasso either says there is a cookie and it's valid or there is no cookie and instead of in that partially, in that public mode instead of sending back a 401 it just still sends back 200 it just sets a blank user. So basically lasso will never send a 401 response in that mode. Okay. Which means you have to set, you have to trigger the log in manually and your app has to send the right response to say force the log in. You actually have to just like build the log in link. Okay. So you actually, this is how the live example is actually configured. If you look at stats on, well actually I think I have a, it's not touch screen on my time. So this is what it looks like if you look at this well that looks great. I think I think this is what I was mentioning. I don't think I set up a process monitor on lasso when I was running this and I think I was SSH'd from this laptop running it. Anyway, what I was going to say was there is like an actual link on that page that says log in and that's just a link to log in dot along with a couple of parameters and that starts the log in process. Okay. And yeah, when lasso is not running you get a 500 server error because Nginx tried to send the sub request and it failed. So like there isn't really anything else it can do. The good news is that it fails securely and doesn't allow the request through because this is actually protecting a secret stuff in the back end you wouldn't want lasso crashing to result in the data being public. Thanks. Anybody else? So I know you're not necessarily the author of lasso but I was curious, one of the things you maybe hinted at or maybe I just wanted to hear are you able to actually authenticate and specify like people who are in certain private GitHub groups for example? No, there's no group stuff in that yet. I think that would be a great addition to it. Patches accepted. Patches accepted for sure. And I think that would be a really good use for it. It's something that I use a fair amount to try to do some and we'd like to have some public facing community stuff and then some only people who have agreed to our sort of user agreement to be able to have code access per se. And using GitHub groups to manage that makes a lot of sense for sure. I think it's a great idea. Worth filing a feature request at the very least on the project. I just started the server so this is what it looks like now. So there's the login link and you'll end up seeing, you get taken to GitHub and then you log in and of course it's making me confirm my password. And we're back. And if I click log out and just get taken back here and now since I'm already logged into GitHub and I've already authorized the application, you don't even see it happen so fast, which is pretty cool. I think that's about the end of the time. Thanks for all the questions. Thank you. I'd like to take this moment to also promote the party that's happening tonight at 7. It's going to be the best party ever. So it would be great if you guys could make it. Will there be Omicronus? There is going to be cotton candy. It's going to be here downstairs in the lounge area. Yeah, here at 7. It's going to be amazing. Thank you. Can I ask you a question fully unrelated to this talk? Sure. I just started getting started with MicroPub and one mentioned like two years ago. Awesome. I think I mentioned you on MicroPub. I doubt you checked it.