 Do I need to do anything about the mic? Probably not. Okay, so thanks for being interested in authentication. Here's the situation. You have a application that you've developed, and a large organization is interested in it, and they would like to either buy it or deploy it, and you are excited about it. And the thing is, you've probably built it around Django Contrip Auth or something like that, and maybe you've extended it a little bit, and maybe you've added a nice management interface. But the organization wants all employees, all associates to have access to that application. And perhaps not just the employees of that application, but they have partners and suppliers and maybe customers, and all of their people should have access to it. The workflow, the ideal workflow is like this. A new person joins the company. HR is a good HR, and they put the person into their central identity management system, active directory, possibly. They put the person into groups that somehow match what the person is supposed to do, or groups to which the person belongs. And when the person then finally gets their password and logs in, they should be able to log in to any service that is somehow related to the work that they do. So if you hire a new finance person, that person should be able to log in to their finance accounting or whatever application right away. If you hire a new network administrator, again, they should get their laptop set up, log into a domain, perhaps it's a Windows laptop, and then access their network management system, network administration, and be allowed to log in. And vice versa, the finance people should not have access to the networking management, and the network administrators should probably not be able to access the tax records. The problem is that no one will enter those users into application in large organizations. So when a new person is hired, that application somehow needs to learn about that new person and about their access rights right away. No one is going, none of those administrators are going to type that person's details into multiple of their applications. They only want to do it once. Moreover, different organizations have different ideas and different requirements about what authentication protocols are to be used. Sometimes it's Kerberos, typically if you have active directory. Sometimes it's some chip cards. Sometimes it's SAML, especially when you want to integrate with other companies. Sometimes, often, the organization has a verified and audited method of setting up those authentication mechanisms using some front-end HTTP servers. And they won't change it for your application. They have standard that they won't use. So I'll probably do it the reverse way. I typically do it. I'll do a demo first, so that you know what I'm talking about. And if you think that it's too easy, you can leave and won't suffer here. So I have free IP server, which is basically something like active directory just on Linux. And I have Bob account created here. And I have a very simple jungle application. The application looks like this. It just shows who is logged in and it shows the last login attempt. So we are currently not logged in. Only admin has ever logged in. That's the situation. And I also have identity provider, which is basically which provides me with SAML assertions. And it's connected to that free IP. So I have three machines. Bob currently only exists in that free IP server. Now, I can do it two ways. I can either click login here in that application, or I can click login here in that central single sign-on solution, which way do you prefer it? Okay, so please log in. I'm Bob. I know the password. I get logged in. Welcome, Bob. Now, when I come to that application, I'm currently not logged in. I click login. I got redirected to that identity provider. I get redirected back. The log now shows that at 12.35, it's GMT time, so it somehow matches the reality. Bob has logged in. And not just that, Bob has acquired some privileges in Jungle. Now, well, either say wow or leave, because that's pretty cool. At the end, I'll show you the same with Kerberos. And at the end, you will be able to pick your own login so that you know that I'm not faking it. So do we do it? I will assume that we have Apache, that Jungle is running under Apache, and that we want it to consume that typical standard remote user authentication result. So how do you do it? Well, since Jungle 1.1, you have remote user middle bar. So that's easy, right? You set it up. But at least two problems. First, remote user middle bar really expects all URLs or accesses to be authenticated. So even if, as the result of that access, and what I did not show you, and I probably should, if I look, I have two different Firefoxs running. So if I refresh the view, you can see that Bob account got created. And actually, we not just know that it's Bob, we also know his first and last name. So there's more than just to the login name. But remote user middle bar wants that login name to be present in that remote user variable or whatever you call it, upon every request. So you would even need to maintain some sessions in Apache, which is kind of duplicating what Jungle does anyway, because Jungle created a session, right, for us. Or you would need to re-authenticate upon every access. That might have been fine when HD password files and basic authentication was used. It's not fine if you use Kerberos, because you don't want to renegotiate upon every request. You don't want to renegotiate upon every renegotiate summer. Second problem is, if you use the standard AuthViewSlogin, it does not really understand when the user has already authenticated via some middleware. It still shows that login page, even if the Jungle Authentication session has already been created. What's the solution? Well, how do we want it to work? We want external authentication, the one that the organization requires, be it Kerberos or GSS API in general, be it SSL, being SAML, I'll show some example with mod.autmelon. We want it to be only created or only enabled on one login URL. The URL that we were clicking here were, let me log out from single sign, otherwise I will not be able to log out here. This is the login I'm talking about. For some reason it doesn't show the URL, but it's slash logging. The solution to the first problem is coming in Django 1.9. We have new authentication middleware called persistent remote user middleware, and it basically does what it says. It will only require that remote user external authentication to be present when the Django authenticated session is created or when the Django session is marked as authenticated, and it will basically preserve it until you log out in Django. For the second problem, I've come with a solution which basically I'm seeking some comments about that user is authenticated, but unfortunately we need to write our own view or a login, and of course it can inherit from the standard of use, but if we check that the user is authenticated, we just redirect to whatever the landing page of that login page is. So if the user happened, if we click the login page the user happened to be authenticated before the handler got chance to be involved because some middleware kicked in and found that remote user populated. We'll just say, well, okay, you are authenticated fine. Django upstream is not currently very happy about this being the default, and so at the end of the presentation there will be more links about how we want to solve the problem. Maybe even is that a problem at all. Now, if you have a modern application, the username that login is not enough. Applications want to send notifications to their users, so they need some reasonable email address. Applications want to show welcome David when David logs in and welcome Bob when Bob logs in, so they want some additional attributes about the user. So here's the proposal. Since we started with the remote user for the login, let's use remote user and underscore attribute for attributes of that user. Now, we've actually done that in other non Django, non Python projects, and it seems to work pretty well. If you are using SSSD-based installations, you can use mod-lookup-identity Apache module to configure basically mapping of LDAP or other attributes to those environment variables. If you use mod-automalon for some, you can do the same. So it's possible with, if you are depending on external, maybe Apache, maybe nGenX in the future, maybe some other front-end server, but if you are depending on external authentication, we should also somehow expect that external environment, that front-end HTTP server, is able to populate some other environment variables or headers, whatever you call it, then just remote user. How do we consume those attributes in Django? Well, I have remote user after middleware, which basically checks that the user as we see authenticated in Django is the one matching in the header so that there's no mismatch. And then it just uses those attributes, sets the attribute, uses those environment variables or meta-values, sets attributes for user and saves. This is a pointer if I had a pointer. So what this means is that upon every request, not just remote user middleware creates the user, which is what you would, what would happen normally, because you need that user record created in your application database, otherwise your foreign keys won't match or won't have anything to point to. But we will refresh that user record whenever authenticated session is started. So we have fresh data about the user. By the way, fearfully to raise your hand and ask at any time when you don't like something or when you're confused or when you want to add something. Now, that's nice, but I said that we also want user membership to somehow relate to permissions that the person has in that application. So the networking people, network admins, will be put by the HR to some groups, which will make them have more privileges in the networking application than the normal people. And it's not a bullying thing. It's not like you either get in or you're completely out because, for example, how does people, you often want them to have access to everything but read only so that they can check status of things. My background is system and network administration. So if I have IT help desk, they need to be able to see into things. They should not be able to modify anything or only a few things, maybe. So based on their group membership, group membership in Active Directory or somewhere else, they should be given application-specific permissions. The similar way, if I log in back as Bob, the similar way Bob got his three permissions here. So here's the proposal. Since we don't want to tweak the Django schema too much, we could have added special model, special database table to somehow hold the mapping. But let's start small proposal. If a group in Django starts with X-con, whenever an externally authenticated user logs in, populate his or her membership in those X-prefixed groups with whatever groups you find coming with that user. And vice versa. If the person is in that X-prefixed group and no longer you see them being member of that group when they're authenticated, remove them, so that when the person changes departments or is no longer working on the project, you have one central place to do that setting and it gets propagated to any application which gets hooked to the central server which is a similar mechanism. At the same time, if the administrator admins need to say that, yes, this person, even if they are not network administrator person, they will need to have certain permissions. They can use any other non-X-prefixed groups and manage their permissions anywhere they like. I'm just proposing that those X-prefixed groups are somehow special and yes. I'll show the code that does it. So one possibility is to have a separate... You probably don't want that, but one possibility is to also get users affiliation or walk authentication mechanism or domain. They spotted a problem. I did not want to get that deep in this talk, so you are ahead. So we said that we would have... that we could have remote user email for email, so why not have remote user group for groups? And the way you can set it up in modlookup identity which does lookups using SSSD, it's an OS-level authentication and identity solution. And the way it is possible in modaut-melon in the coming version that I hope will be released soon is that it populates group underscore n so that you know how many groups are coming and then you have those individual variables with separate names. And another possibility would be to have it just call and separate in one value. That's also a possible way to do it. And then we have the middleware and yes, the prefix is somehow hard-coded here because I thought that we need to start small and start somehow. And then we look at the groups that we get. We look at the groups that we currently have and we basically update what we have and then call this and save the user and update the user. So I showed you how it can work with SAML. Let me do it with Kerberos. Let me log out so that we have somehow a one-on-one state. What user would you like me to create? Come on, say something. You'll be very silent. Any or Penny? Penny, okay. Let me give her a password. Let me try to make this small so that you can see more. Yes, works cool. And I will not just create the account. I've been speaking too long so I need to re-authenticate as administrator which would be much easier if I saw the bottom of the page. Okay, so we have Penny created and let's put Penny into network admins group because she's joined the IT department. So we just created Penny. Let's change email address. Why do we have email addresses here? So that you can trust me that it's not just faking it. So we have Penny created. Sorry. We have Penny created. Let's pin it as Penny, Kerberos, slides, realms. By default, VIP creates the user with the password expired so I had to change the password. But I have a ticket granting ticket for those of you who are fluent in Kerberos which basically means it's a good thing. So let's verify what we have in the Django application. We still only have admin and BOP. And now, well, now I need to change the configuration of that application because Y is the client for some of here. So let's remove that. I could have used both, but I don't want too complicated things. Django, Extran Configuration, let's put it. Restart Apache. And so I'm blocked in, single signed on. This is what you would see. You would see ATGT if you blocked in on your Windows machine as well. Let's click Login. Now we can see that Penny has logged in, even if she did not have any account there. If I refresh now, the account is there. I can see that her email address is there all right. And I can check that Penny is a member of X Network Admins Group. So her group membership that I created, that I set up in free IPA, got propagated. And if I look at that Network Admins Group that I had pre-created, you can see that it has listed these four randomly just for the purpose of this presentation permissions. And if I look at what the application says to Penny, it lists just exactly these four permissions. Conclusion. It is possible to support multiple authentication mechanisms without writing Python code. Now this is a Python conference, so you might not find that a good thing. But first it might be required that a front-end authentication should be used because it's what the company or government body uses. And that implementation might actually be much harder than you can imagine if you start from scratch. In Django 1.9, it is possible to easily use authentication enabled, that external authentication enabled in Apache or in another front-end server, just for the login URL. And it will survive. It's that persistent remote user mid-war. You need to be careful, especially if you want that login page to still be available when the external authentication fails because you might want users to use Kerberos but fall back if they don't have a ticket. And by the way, just so that you trust me that Kerberos happened, you can see the HTTP service ticket was created. So it really was Kerberos that authenticated Penny. Now, yes, traditionally, remote user was what authenticated users. And in Django, we had the functionality to create that user automatically about the first login for some time. But these days, you probably want more than that. Attributes of that user, and yes, you need to find a way to somehow match what you have in your corporate identity management to what attributes each and every application adds to the model. And more importantly, group membership because you can link permissions to groups and have those permissions pre-created and predefined and when the user gets created, they get propagated and you can use them. Again, we were not writing a lot of Python code. We were not writing SAML or Kerberos in Python. We are just consuming external authentication. Depending on your view, it's either a good thing or a bad thing. So I welcome your questions and comments and here are some links to go with this presentation. And now really ask me some questions. Actually... What about federated logout? First, it's hard. Second, the epsilon identity provider does support it and SAML does support it, but depending on the protocol use, it's either possible or not. So if you are thinking about a kill switch, if the person gets fired, so they're really logged out, I don't think that you'll find a solution, like a standard solution. So I was not focusing on that. Would you be using the same method if you were using OAuth or something like that for login? For end users visiting the gentleman in the back? My question is actually pretty similar. I thought about more OpenID Connect. So when I already have a single sign on based, for example, OpenID Connect or anything else, do I depend on the implementation on Django that it's possible to connect it or how does it work? Because you were talking a lot about Kerberos or SAML. So what is really necessary that I'm able to connect my single sign on? Well, my answer would be, what does your Apache support? Because I'm really trying to not do it in Django. I'm trying to build a... Framework is a bad word, but I'm trying to find a approach in Django which would make it possible to use what maybe other languages and frameworks use. So if it's implemented for Apache or for some other front-end web server, then you should be able to consume it this way without having direct support for it or direct knowledge about that protocol in Django itself. Yes, but at the end of the day you get authenticated user and some attributes. So what I'm saying is don't try to... Or maybe you don't want to try to address it in Django. Maybe you want to find an existing solution for that and just consume the result. And it does not really matter how many round trips the protocol mandates to get the user authenticated. Eventually you will get the remote user or the indication that the user has authenticated and that's what we use here. Hi. Hello. We actually used to work together. I'm wondering if you have ever made a similar Django app but with Uwuzgi or something else other than Apache. With what? With Uwuzgi or some other server other than Apache. Well, we actually had a person working on the module on the modules for Nginx. So we're trying to somehow expand the approach to non Apache but we are still only focusing on Apache as our main thing. And again, it would be about implementing those protocols in those additional servers and then consuming the result in hopefully a standard way. Okay, so thank you. Everyone, please thank you.