 Hello everyone. Welcome back to the session after break. Next up we have Vibhu with us. He is an open source enthusiast who has been participating in meetups, doing talks, helping people learn Python and all. So he will be talking about developing a single sign-on service using Django. Over to you Vibhu. So am I in the screen? Yeah, you are. We are live. Okay, thanks. So hi everyone. Hope everyone is happy, healthy and comfy at the place. And welcome to the talk. So we're going to discuss a few concepts before we move into the implementation because once we know the concepts, the implementation is going to be really simple. So just took you a quick introduction about me. I'm a student. I've been using Python for three years. I've been using Django for two years. And I'm also back in developer intern at big studios. And we recently developed a single sign-on service, our custom single sign-on service to authenticate our users for our product of services, product app or services. So what's single sign-on? Now it's a thing which enables service providers to implement such a thing where the user don't have to go signing in through different portals and their users just have to be signing in at one place and they're good to go. So just like by using Google Docs or Sheets, you don't have to go through Sheets signing in page or Gmail signing in page. You just have to be signing in through Google and you're good to go. You can access whole suite of the services. So why are we even discussing this? Is it any good? So let's see. For users, they don't have to remember a whole lot of passwords. They just have to remember one password and they just have to be signed in at one place and they're good to go. And that provides a very good user experience, of course. For service providers, managing becomes a lot easier because you've got to just maintain one database and don't have to worry about maintaining different databases in different services because you've got only one database which has all of the information about all of the services and about all of the users in all of the services. And that goes for the session as well. Now sometimes you've got to provide some manual user account support as well because sometimes passwords get lost or something happens with the user account. So again, you can put all of your efforts in maintaining just one user account support staff. Now sometimes you add some extra security layers in your signing in mechanism, like two factor authentication. Now, because users just have only one place to sign in, they don't feel annoyed in getting through the security layers. They are more secure and thus making the whole suite of your services more reliable. So how does this thing work? Let's take an example. So suppose you visit the Google Docs homepage. You go to the homepage and see the catalog. Now catalog looks good and you say that I want to access a document. But the document says that no, your document is locked and you've got to have a key to open this. But you say that I don't have a key. So the doc says that, okay, you can get the key from one particular shop. I recognize and you can get to the shop and get the key. Now you said that I don't have this address and the docs give you the address. Now you go to that shop. At the shop, they ask you for some details. You enter your details and you try to just give in your key. Now at the back of the shop, your details are checked and if your details are correct, you are issued the key which you were looking for. Now you hurry back to the docs and give them the key which you got from the shop. At the back of the docs, they check your key if it's not any cheap metal or you bought in some from any random vendor. Now if the key opens a lock, you're provided with your document which you were looking for. Now let's throw in some technical terms in here. Now you are a resource owner. You are asking for a resource. Now because that resource is locked, that resource is protected, we're going to term it as protected resource. Now you resource owner go to the client and ask for a protected resource. From there, you redirect it to a sign in page. Now sign in page is usually the authorization server frontend. Now authorization server is a place where your details are checked and you're issued tokens which are basically the keys. Now tokens are of two types, access and refresh tokens. Access token is the thing which is going to fetch you your protected resource. Now access token is passed to the resource server. Now resource server acts as something like your sheets back end. It's going to be something like your sheets back end or your docs back end. Now the resource server, your tokens are checked. If a token is valid, you're provided with your protected resource back at the client. Now this is one of the standard implementation of single sign-on and we have a few others as well. And we also have a few protocols to just which go along with those implementations. SAML and WSFED uses XML as the data interchange format. LDAP-ED is also popularly used in single sign-ons where we've got one directory and multiple applications can just access that one directory which has all of the user information and that uses LDAP-ED to interchange format. Now OpenID connect is the thing which we have to focus on. We recently discussed access and refresh token. Now access token handles the authorization part and that comes with the OAuth. Now what is OAuth? OAuth is a security standard wherein you give permission in one application to use the data in some other application. Now OpenID connect is the thing which sits on top of OAuth. Now this layer brings this ID token along with it. ID token is in the special format in JWT or JSON of tokens. It contains some extra basic user profile information as well. So that handles some authentication details as well, authentication part. Now for comparison, we've got OAuth which provides you an access token or basically a visitor batch. Through that visitor batch you go into the building, you go to the counter of the building, you show your visitor batch, you're allowed to go in. You roam around the building, people can see you, see your visitor batch, but they don't know anything about you. And contrast with OAuth, OpenID connect gives you an ID token. ID token is similar to your employee card. Now employee card has some user information, your mobile number, there's some designation and some other details as well. Now using the employee card, you can't just only roam around the building. You can also get through those stuff which only allows employees to get in. Now we discussed ID token in the form of JWT. Let's quickly go through that. Now it's in three parts. The first part is the header, the second part is the payload which contains the claims of user profile information, and the third part is the signature. Now signature validates your JWT or basically if your JWT has been tampered with or not, or it's been expired or something like that. Now secret key is the thing that goes into this complex algorithm. Now this secret key, you've got to keep that secure. The secret key is a thing which is used to sign your JWTs. Now because if you let in your secret key go into some attacker's hands, they might actually have, you might actually face an identity theft. They can just use your secret key to just mimic your identity and sign the JWTs with your signature. So again, you've got to keep your secret key secure. Now we discussed access and refresh tokens. You know that access token is used to fetch your protected resource from the resource servers. Now what's the use of refresh tokens? A refresh token is a thing which fetches you more access tokens. Why would you need more access tokens? Now here's the thing. Let me tell you some few facts about the access token. Access token can be passed to multiple resource servers and access token is usually passed in HTTP request headers and not in more secure post data. Now because access token is passed to multiple resource servers and consistently passed to multiple resource servers, it may happen that your access token get logged somewhere and some attacker gets your access token. So to solve this, to tackle this problem, we have a thing called expiry time. That's the same thing as expiry date that goes onto your packets. Now expiry time is attached with both access and refresh tokens. Access token is usually given a very short expiry time of about five minutes or so. So even if your attacker gets your access token, they do have a very short window of time through which they can just use their access token to mess up with the data. Now refresh token is a thing which has more or longer expiry time of about 10 days or so. Now you can use a refresh token to get more access token and then just get a fresh stream of access token which will be valid for further five minutes and then you can just go along with your business of fetching your protected resource from the resource server. Now that was a lot of concept. Let's go into our demo. So we have our cute little Django server running over here and okay, we haven't opened Postman yet. So that's the thing. Ah, shouldn't put the Postman demo over here. Yes, it will use HTTP. Okay, till the time I open Postman, let's quickly go over to what database we would require if we go about implementing this thing, this single sign. Now we discussed that we're going to have this one single user table and multiple services will be just connecting the user tables with the central user table. Now along with the user table, we're also going to store some information about which services we have or which products we're going to offer and what are the connections, which users are connected to which services or which products. Now I guess the Postman must be up by now. Let's quickly see what we meant by our access and refresh tokens. So this is the endpoint which is going to purchase our protected resource and we send in a request and after sending the request, it says the authentication credentials are not provided. Let's get some credentials from our server. So this is our server. We pass in the post data with our credentials, not so secure password, which will do something like this. So get your access token. Now access token is a thing which is going to fetch you the protected resource. Now Postman has this nice little feature where we can just embed a token. We embed our freshly obtained access token and we get a message, our protected resource. Now if we see the headers which were passed to the request, we see our token. So as we discussed, the token was using the header and not in the post data. Now let's see what's in this GWT. Let's copy this. Okay. We're going to copy this. And we go to our GWT debugger and we paste our token over here and we see this is the claim which was embedded inside the GWT. Now we have this token type which says it's of type access, not refresh. It says expiry time, which is valid for another five minutes or so until 1540 and GTI is the unique identifier of this claim of this GWT. The user ID is the information about the user. Okay. So let's get back to the slides. And as we discussed, we're going to have three tables in our SSO or single sign-on database, the connections, users, and services. So now before moving further into the implementation, we've got to remember a few things. Now the two things, the primarily service providers and not primarily identity providers. Because sometimes you use third-party identity providers as well. Because sometimes you try to log in into the GitHub through Google. And that way Google acts as a third-party identity provider. That won't be the case with us. Because in that case, what GitHub shows you or signing in through to GitHub through Google shows you that you will be used, your Google account will be used to fetch your public information and no other information like contacts and stuff. So this is this you must never have faced while using docs or sheets because that is directly provided by the Google. Now that will be the case with us as well. We will be directly providing the services as well as the identity. So there won't be any consent requests in our case. Now sometimes it happens that your organization gives you an email. Now using that email, if you sign in, you get only a subset of services which are provided by the service providers and you won't have access to all of the services which are provided by the service providers. Now let's just revisit the flow once again. For a change, we will just sign up instead of sign in. So you resource owner, again go to the client and ask for a resource server. You are taken to the sign up page and from there the authorization server then issues your tokens. Now before issues, it issues tokens, what it does, it issues all, it relays all of the information which is acquired of the user to the resource server, to a service or a product. Now it's that. So for example, we discussed that ID token is in the form of employee card. Employee card can have some information about the user, like name, mobile number, which cannot have all of the information that might be required by the office of the user. So for that same reason, what authorization server does is just relays all of the information that might be required by that service or product for that user, for that user. Now the resource server has all of the information required to act upon our business use case. So whenever user comes in, they go to the home. So as you can see over here, we have authorization server and resource server separate and that's important because we have a secret key that can be only at one place and has to be secure. What, how about we distribute a secret key? So the problem was that resource server wouldn't be able to validate the legitimacy, they don't have the secret key. So if we distribute the secret key to the resource server, now they will be able to just validate the JWTs. Now, sometimes it happens that it may happen that sometimes shady, shady is sitting at the resource server side. What they can do is just mimic the identity of authorization server and then you have an identity theft once again. Now you don't want that identity theft. For that reason, let's consider a second solution to have a dedicated token verification service. Now what happens in this design is that you have two services over which you have full control. One is the verification server and one is the authorization server. Authorization server, of course, will be issuing the tokens and the verification server will be validating the tokens. Now resource servers would just be sending the request, sending all of the authorized request to the verification server. Now verification server would just be validating the JWTs and sending that the JWTs have been valid or not. Now that introduces one important identity design as well. Now what happens if a verification server just gets a load, whole lot of traffic and just goes down. Now all of the resource servers won't be able to just validate the JWTs so no authorized request and no user-related queries. So to tackle this, let's consider our third solution. What if we break our secret key into two parts? One will be termed as private key and the other will be termed as public key. Using the private key will only be signing the JWTs so that's one part of a secret key and the other, you will be just be validating the JWTs. So what will happen in this is you can just keep your private key secure and you can keep the other half of your key this public key and just distribute to the whole world and you don't have to worry about they will be just mimicking the identity because using the public key, you would just be validating the JWTs which are authorized or signed by the public key by the authorization server. So, I guess we discussed most of the concepts that we needed for implementing the single sign-on and of course we are not directly implementing OpenID Connect it's very much close to that. Now before moving into the implementation, I want to discuss just one thing that we implemented at Vega Studios so that we don't get lost in the code. So what we are expecting that companies or organizations or teams will be coming to us and they will be asking for subscriptions for products like they will be interested in product A and C and not in B so they will be subscribing to that service or product. So we got to maintain a table to store the information about the organization and one table for managing the information about subscriptions. So we have these five tables in all in our single sign-on or authorization server. So now, diving into the implementation we have a Django server and Django REST framework we have a simple JWT library which we will be handling all of our JWT stuff, request library which will be used for the request between authorization server and the resource servers and our cryptography library which will be handling our public and private keys. Now the core of our Django project of course now we will be having two apps users apps will be storing the information about users and organizations and services will be storing information services connections and subscriptions. Now REST framework is coming from Django REST framework of course. Now let's generate a private key. Now using the RSA module that's the asymmetric signing algorithm now you can use the generate private key function and you can specify settings like specified 4096 bits long that the size I want my public and private keys to be and then you can just serialize a private key and then just save it in a file using the file operation. Then you can do the same with the public key and now you have got your public and private keys saved in a file. Now the settings about the JWTs now you've got to just configure the settings in a dictionary which and you assign it to a simple JWT variable and that will be used for settings of our JWTs. Now focus on the first two keys over there. You've got your access token lifetime and the refresh token lifetime that is the reference with that we talked about. Now notice that access token has an expiry time of about 5 minutes or so whereas the refresh token has an expiry time of about 1 week or so. Now algorithm is the RS256 that's an asymmetric signing algorithm. Signing key would be our private key of course verifying key would be our public key. Audience is a thing audience is a reserve claim inside the JWTs which is used to just denote for which audience is a particular JWT valid for. Now you've got to provide this JWT authentication class as well in your default authentication classes that will embed the user information inside your views. Now after configuring these settings you will have a JWT which will look very much similar to the one which we just basically saw earlier. Now moving into the models we've got two models, user models and organization models and the services models which has the information order service and the connection which is the user and the service, subscription model which will be connecting service and an organization and now what we want to do is expand the reach of our JWT. What we want is that particular JWT should be able to just verify more products not just one product and what we want is our audience claim, good audience claim and we're going to just embed all of the identifiers of all the services of products inside the audience and the JWT is now ready to be distributed to multiple resource servers. Let's see that in action as well. Now we have our single sign-in server running that will be just reflecting our authorization server. We've got a standalone service running which is reflecting our resource server and now let's see what's there in the database of our standalone service or our resource server. We sign in using super user credentials and we see which user is there. We see that we have got three users, single sign-in admin, super user and some organization admin which we don't care for it now. We're actually going to use the credentials of this organization admin. Let's quickly close these tabs and we're going to use the end points from our single sign-in. Let's just get the tokens from our authorization server. That's it is there for right. We've got our access token. We're going to just copy our access token using in the different requests and let's see which users are there inside our organization and we paste in our access token the authorized request. We see that we have one user in our organization that's the test user but this user must not connect it to that resource server because the resource server doesn't have any information about this test user one. Let's just connect this test user with our standalone service. Let's see what's the detail of this service. What are these services in our database? We've got our standalone service that has the idea of one and now we're just going to create a connection between the test user and our resource server or standalone service. The body of this is expecting a user ID. We just pasted our access token over there. It's expecting a user ID and a service ID. We're just going to use our user ID from here. That is our test user once ID. We're just going to copy the ID and paste it over here and similarly going to just fetch the ID of service. That's one should easy to write and paste it over here. And now we've got instance that represents a connection that user is connected to a service and the connection is of ID too. Now let's see our server once again and refresh the page. Now you see that the test user details are there inside this resource server. So the authorization server must have related all the information of the test user to a resource server. Now that is how your authorization server and resource servers would be working together. Now let's just use the credentials of our newly connected test user one. This is the credential of test user one. That is test. We're going to use credentials of this test user and it's not a cheesy admin. So based on our credentials and we've got our access token from our authorization server which is different from our resource server. Sorry to interrupt you you have five minutes now. Okay wrapping it up. Thank you. So we're going to just embed a token inside over here and there we go. We got our protected resource from our standalone server. Now you're obviously going to have we're not going to have Hello Python users but we're going to have a protected resource every time. Now this is how you're going to just fetch your generalities from the authorization server and then just pass it to multiple resource servers and the generality will be valid because it will have the claims inside it and that will be valid for all of those services. Now of course for our embedding of this JWT is what we're going to do is just where you're just going to embed the claims of or identify all of the services inside your token what we're going to do is just use the custom token obtain preview and that you inherit from token obtain preview which comes from simple JWT and similarly you're going to use your custom serializer from there. You're just going to fetch all of the services for which the user is connected to and you're just going to pass the identifiers of all of the services to which the user is connected inside the service. Now you have your audience claim which will just be valid for all of the services. Now for the creating the service or connections or other endpoints I use the general KPI views of press framework and they provide a very awesome documentation to just read, you can just read them out and it's very good and of course you can mention your serializer which contains all of the fields with which you will be there in the JSON object and you can get, there's a quote of all of the different projects or the different servers that is the authorization server and the standalone service in the link given at the bottom of the screen and of course you can consider all of these links for other resources as well and thank you, thank you very much and I'll be taking questions on either Zulep, LinkedIn and you can ping me on telegram as well and thank you I'll be connected now All right, it was really interesting talk you had it well structured the way you delivered, I really liked it cool, so folks you can find Vibhu in the Zulep stream for Hyderabad which is 2020's less traced as Hyderabad and you were saying something I'm proud of it, thank you