LDAP Authentication/Authorization

Jump to…
ldap

Authentication/Authorization

How to use LDAP.RUTGERS.EDU for Authentication

You can check a user’s password by doing a BIND to the DN for that user. The code should look like this:

  • Connect to ldap.rutgers.edu, port 636, via SSL
  • Bind to your service DN, which is issued by LDAP Support
  • Look up the user you want to authenticate, probably doing a search with a base of ou=people,dc=rutgers,dc=edu, and a filter of (uid=NNN), where NNN is the person’s netid. Of course you can do lookups by other attributes in the schema.
  • Bind to the DN returned by that search, using the user’s password.

MSSG has code to use ldap for authentication for the following environments:

  • PHP applications using Apache
  • Applications using IIS (a COM module)
  • Login authentication for Linux (a PAM module)

In case you prefer to use Microsoft’s LDAP support rather than our COM module, here’s an example that uses ADSI to check a password and then retrieve some attributes of the user.

Here is another example of PHP:

Here is a Java example:

We have information from the NB/P Faculty of Arts and Sciences on

This is one of the best ways to use University NetID’s and passwords with Windows.

Authentication and Authorization Information in the Directory

Just to be clear: authentication is checking who you are; authorization is checking what you are allowed to do. In this context, authentication is checking your password, authorization is checking various LDAP attributes to see whether it is appropriate for you to do something.

Authentication

LDAP can check passwords. In fact typically a connection to LDAP starts by doing a “BIND” operation. This takes a user (in the form of the DN for the user) and password, and succeeds only if the password is right. It can also do authorization, as discussed in the next section.

In general we take the view that authentication and authorization should be separate. Thus we’ll verify a password as long as we find a valid password for the user, even if they have been disabled for displinary reasons, and even if the password has been locked because we think a hacker knows it. Locking people out is authorization, not authentication.

By separating authentication and authorization, we allow departmental applications to use us to check the user’s standard University password, but make their own decisions about what users they want to allow. We provide a mechanism for departments to pay attention to OIT decisions: If you want to reject users that we have locked out, you can do that. But you can also make your own decisions.

Authentication Types

It’s worth noting that users may have multiple types of authentication. The default for most users is Kerberos. However some users will also have accounts using Safeword one-time cards. Those users will have two authentication entries, “default”, which has their Kerberos principal, and “safeword”, which has their Safeword principal. (For historical reasons, “enigma” will work as a synonymn for “safeword”.)

Normally a BIND operation will use the default authentication entry. However you may prepend auth=XXXX, to the DN to force another type of authentication. To force Safeword authentication, you would bind to auth=safeword,uid=NNN,ou=people,dc=rutgers,dc=edu.

In some cases you may not have control over the application, so you may not be able to get it to prepend auth=XXXX, to the DN. For that case, we have a kludge: You can prepend auth=nextsafeword to the initial bind using your special DN. That will force the next bind in this session to use safeword. An example may clarify this. The usual sequence of operations is

  • User types username, password
  • Application connects to LDAP, binds with applications’s DN, e.g. uid=dept.auth,ou=Special Users,dc=rutgers,dc=edu
  • Application looks up uid=NETID, gets back user’s DN
  • Application binds with user’s DN and user’s password

To do Safeword authentication, you could do the following

  • User types username, password
  • Application connects to LDAP, binds with applications’s DN, prepending auth=nextsafeword, e.g. auth=nextsafeword,uid=dept.auth,ou=special users,dc=rutgers,dc=edu
  • Application looks up uid=NETID, gets back user’s DN
  • Application binds with user’s DN and user’s password

By using auth=nextsafeword with the application’s DN, the next bind will use safeword (assuming you are using the same LDAP connection). That’s the bind with the user’s DN.

Currently safeword and nextsafeword are the only useful values for auth=. auth=default can also be used, but since that’s the default it’s unclear why you would want to. For historical reasons, enigma and nextenigma can be used as synonyms for safeword and nextsafeword.

[NOTE: This is clearly a hack. The “correct” way to do this would be to define a SASL authentication type for Safeword. However SASL types are implemented in the LDAP libraries, so to add a new SASL type all clients would have to use modified versions of the LDAP libraries. Adding a SASL type goes beyond what you could do in PHP, ASP, etc. We’ve opted for techniques that are easy to use on the client side.]

Authorization (Limiting who can login)

Every application needs to do authorization. We have valid passwords for people who are no longer associated with the University, whose passwords have been compromised, etc. So applications need to choose what users they will accept.

There are two ways to do this: you can let LDAP do it for you, or you can build it into your application.

By default, LDAP will only verify passwords for users that OIT considers active. That is, by default, we do both authentication and authorization for you. However you may choose a different approach.

  • You can ask us not to do any authorization at all. In that case we will verify any password we know, even if the person is not a valid user. This is the right thing to do if your application can check who is valid.
  • You can ask us to do authorization, but to follow a different policy. That is, rather than allowing anyone that OIT considers a valid user, you can ask us to allow only students, only members of your department, etc.

Note that it is possible to combine these approaches. For example, you might have an application that can tell whether someone is a valid user, but you might still want us to refuse users whose passwords we believe have been compromised (i.e. are known to hackers).

If we do authorization for you, it is based on your service DN. That is, each department or application using LDAP will have its own DN, typically something like uid=mydept.auth. That DN can have a “filter” associated with it. E.g. the basic filter is

(!(|(rulinkRutgersEduStatus=inactive)(rulinkRutgersEduLock=*)))

(This is slightly simplified. The actual filter is discussed below.) This filter says that the account is believed to be active, and that it hasn’t been locked because we think the password is compromised, or because the user has done something to cause disciplinary actions.

You could also ask us to add tests verifying that the user is a faculty member, a member of your department, etc.

The filter will apply to any session where you have first done a BIND to your service DN, i.e. uid=mydept.auth.

Because some software doesn’t bind to the service DN before checking the user’s password, we have an alternate approach: You can give us one or more IP addresses. In that case, any BIND request coming from one of those IP addresses will be recognized as coming from you, and will get the filter associated with your service DN. (Specifically, this is implemented by adding one or more attributes rulinkRutgersEduSpecIP to your service DN, with an IP address as its value.)

If you haven’t made any special arrangements, a default filter will be applied to all of your sessions. Currently, this filter checks that the user is considered a valid OIT user. I.e. they have a valid OIT account, and haven’t been disabled by OIT.

If you don’t want us to do authorization for you, we will specify a filter that always succeeds.

The default OIT authorization

This section describes the checks that are done by default, if you have not requested a different filter.

As indicated above, by default we apply the filter

(!(|(rulinkRutgersEduStatus=inactive)(rulinkRutgersEduLock=RUTGERS:*)(rulinkRutgersEduLock=CAMPUS:*)))

rulinkRutgersEduStatus states whether the person is a currently valid, activated user. I.e. they have setup a valid password and have a valid role and/or account on one of the 7 OIT RCI/ICI systems.

rulinkRutgersEduLock indicates that a user’s account has been locked. The default value checks all locks that we consider to apply to “generic services”, i.e. the global locks (RUTGERS) and the locks managed by the campus divisions (CAMPUS). It does not check locks intended for a specific service.

Currently there are four locks:

  • RUTGERS:1 – this is a global lock, that is intended to be set only when there is a clear reason to disable someone in all applications throughout the University. This is a new feature, and policies haven’t yet been set, but it is intended that most applications will pay attention to this lock.
  • CAMPUS:1 – this indicates that one of the campus divisions believes that the user’s password is invalid. In some cases this may be an inactive user whose password has not yet been updated to the current password scheme. More commonly, it indicates a user whose password has been used by hackers. We disable it until the user can change it.
  • CAMPUS:2 – this indicates that the campus divisions have locked a user’s account for disciplinary reasons, or possibly because the user is no longer at the University and they are in the process of closing the account.
  • REMOTEACCESS:1 – this indicates that the user should not be able to access modems and related services.

We will develop more specific categories over time.

Doing your own authorization

You may well want to do your own authorization. Typically you will use your own data, or make checks in the ldap database.

The easiest way to limit who can authenticate is to add an additional test to the lookup. For example, suppose your service only wants to authenticate faculty or staff. After binding to your service DN, you might do a search with a base of ou=people,dc=rutgers,dc=edu, and a filter of (&(uid=NNN)(|(employeeType=STAFF)(employeeType=FACULTY))), where NNN is the username that has been supplied. Or if you want to give different error messages for “no such user” and “you’re not a faculty or staff”, you could lookup (uid=NNN) and ask for the employeeType attribute to be returned. Then you would have to check the returned attributes for employeeType.

[If you prefer, you could ask us to set this filter for your service DN. However this section is written assuming you want to check yourself.]

WARNING: employeeType tracks the status in our administrative data. Depending upon the nature of your application, you may be want to use rulinkRutgersEduCampusService. This indicates how the OIT campus divisions treat the individual. The campus divisions do not shut down access immediately when someone loses their active roles. They check between 1 and 3 times a year, giving people the opportunity to respond before disabling their access. See the sections on staff and student attributes and data flow for more information.

Typically you’ll need to use wildcards when evaluating the rulinkRutgersEduCampusService attribute. E.g. to check for facstaff service, you might want to use a test such as rulinkRutgersEduCampusService=facstaff:*:enabled

Be aware that users do not necessarily have all attributes. Someone who is registered for service through one campus will have rulinkRutgersEduCampusService, and will be able to authenticate. However if they do not have a valid role in the Registry, they will not have an employeeType. Similarly, someone who has a valid role in the Registry but is not registered for a campus service will have employeeType but not rulinkRutgersEduCampusService.

Related Articles