📜 ⬆️ ⬇️

nodejs: SSO authentication via Kerberos

All ingenious is simple. But to this simplicity you need to reread thousands of manuals. Therefore, having understood, I wanted to write a quick start on how to make transparent authorization in a Web application for a user authorized in AD, and share my test project. An interesting look from the side.



First, a little theory. SSO, which is also transparent authorization, is an idea by which a user once enters his username / password in Active Directory when logging on to a computer, and then, opening a Web application (not only, but talking about it) is automatically authorized with data your account

In browsers for this principle is laid down - receiving in response to its Get-request HTTP-code 401 "Not Authorized", and in HTTP-headers <WWW-Authenticate: Negotiate>, he, the browser, makes a request to the KDC (Key Distribution Center - one of the AD services) to receive a special SPNEGO token for this Web service. If there is no account for such a Web service in AD, then the browser takes the standard answer for NTLM authorization. But in this case, we believe that something went wrong.
')
So, in case of correct settings of this Web service in AD, the browser again sends a Get-request to the response 401, but with a header like <Authorization: YIIJvwYGKw ...> If the token starts like this, with “YII”, then this is Kerberos-encoded ticket containing data for authorization.

Kerberos is just a type of encryption, but since it is mainly used for SSO, these concepts are closely related.

Then, after receiving the token, the Web service sends it to the KDC for verification using the kerberos client. And, if successful, gets the username in AD. Which can be further used to search for user data (for example, groups in which it belongs) already through another AD access service - LDAP.

Most clearly describes this process diagram from the official documentation of Microsoft. And, I must say, surprisingly it was their documentation that gave the greatest understanding of the subject.

image
From here

Thus, in addition to creating a Web application, the following actions are needed:

What do you need to do on the side of AD administrators

- set in AD the SPN name for the Web service (type HTTP / webservice.example.com@EXAMPLE.COM). This will allow client browsers to request a token for this service and send it in the HTTP header to the Web service, and the Kerberos client to authenticate users via this service based on the key
- generate the key krb5.keytab for this service, which will be used in the Kerberos client to authenticate users.

Additional actions on the web service server

- you will need to install a Kerberos client (on Windows, it already exists, in the case of Linux — for example, for RedHat the installation command: yum install krb5-workstation krb5-libs krb5-auth-dialog krb5-devel);
- for it you will need to configure the krb5.conf configuration file to access the KDC (as - AD administrators will call the correct settings, the main parameter - kdc);
- and also attach the /etc/krb5.keytab key file.

In a web application

- install the kerberos module, to work with the kerberos client,
- and the module activedirectory, to perform LDAP queries.

One unpleasant moment - for Windows, the kerberos module provides a separate API, and it did not work. If someone has a solution, it would be invaluable help.

For Linux, the kerberos module provides two basic methods that are needed in the work:

- authGSSServerStep - sending a token for verification,
- authUserKrb5Password - login / password authorization, in case transparent authorization did not work.

There is no documentation on the use of methods, but there are explanatory comments in the file lib \ kerberos.js.

Here is the main piece of code that checks the token that came from the browser:

//cut phrase "Negotiate " var ticket = req.headers.authorization.substring(10); //init context kerberos.authGSSServerInit("HTTP", function(err, context) { //check ticket kerberos.authGSSServerStep(context, ticket, function(err) { //in success context contains username res.set( 'WWW-Authenticate', 'Negotiate ' + context.response); res.send(context.username); }); }); 

→ Link to a test project on GitHub

The code has a bonus - a filter for searching all groups of a user, working with a large number of groups an order of magnitude faster than the method proposed in the activedirectory module.

As a result, when you open the page, if everything is done correctly, there should be



Expected limitations:

- the address of the Url cannot be in the form of ip: port, but only with the indication of the DNS name (associated with the registration of the Web service in AD),
- this authorization works only with certain settings of IE, but these are the default settings (“Automatic access to the network only in the intranet zone”, “Enable integrated Windows authentication”). Chrome uses IE settings. Other browsers may need their own settings.

Source: https://habr.com/ru/post/321962/


All Articles