nodejs: SSO authentication through Kerberos

Everything ingenious is simple. But to this simplicity you need to re-read thousands of manuals. Therefore, having figured it out, 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 view from the side.



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

The principle is laid down in browsers for this - receiving in response to their Get request an HTTP code 401 “Not Authorized”, and in HTTP headers, he, the browser, makes a request to KDC (Key Distribution Center - one of the AD services) for a special SPNEGO token for this Web service. If there are no accounts for such a Web service in AD, then the browser takes the standard response for authorization by NTLM. But in this case, we believe that something went wrong.

So, the browser, in the case of the correct settings for this Web service in AD, again sends a Get request to the 401 response, but with a heading of the formIf the token begins with “YII”, then this is a 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 the Web service, having received the token, sends it to the KDC for verification using the kerberos client. And, if successful, gets the username in AD. Which further can already be used to search for data about the user (for example, the groups in which he is a member) through another AD access service - LDAP.

The most vivid description of this process is from the official Microsoft documentation. 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

required : What needs to be done on the side of AD administrators

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

Additional Actions on the Web Service Server

- you need to install the Kerberos client (on Windows it already exists, in the case of Linux - for example, for RedHat the command to install: 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 KDC (as - AD administrators will name the correct settings, the main parameter is kdc);
- and also attach the key file /etc/krb5.keytab.

In the Web application

— the kerberos module is installed to work with the kerberos client
— and the activedirectory module is used to perform LDAP queries.

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

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

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

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

Here is the main piece of code that checks the token coming 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 filter for searching all user groups, working with a large number of groups is 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 the



expected restrictions:

- Url address cannot be in the form ip: port, but only with the DNS name (associated with the registration of the Web service in AD),
- this authorization works only with certain IE settings, but these are the default settings ("Automatically log on to the network only in the intranet zone", "Allow built-in Windows authentication"). Chrome uses IE settings. Other browsers may need their settings.

Also popular now: