Search code examples
single-sign-onkerberosspnegospn

What is the use of the pre-auth user in SPNEGO SSO configuration?


I'm using SPNEGO in order to implement SSO solution. During the configuration, I was required to use domain user credentials in 2 steps:

  1. In the web.xml of my application:

     <init-param>
          <param-name>spnego.preauth.username</param-name>
          <param-value>myuser</param-value>
     </init-param>
     <init-param>
          <param-name>spnego.preauth.password</param-name>
          <param-value>mypassword</param-value>
     </init-param>
    
  2. In the setspn command: setspn -A <mySPN> myuser

When I used this configuration, the username of the user "myuser" was retrieved by the Java application using getRemoteUser(). So the SSO worked fine. But when I tried to open a session as other users (on the same windows server) it worked also, so I am a little bit confused. This led me to these questions:

Why did the SSO work for all the other users of the domain? Do I have to use the same user in both web.xml and setspn command? And which user to choose? What's the exact use of the SPN in the Kerberos scenario? Do I have to execute the command setspn in every windows computer or there is a way to do it just once?


Solution

  • This account is part of what defines the server's identity within Kerberos.

    Kerberos is a symmetric-key protocol. Each user has a symmetric key that's shared between the user and the KDC, and similarly each service (acceptor) has a symmetric key that's shared between the service and the KDC.

    When a user requests tickets for a specific "service principal", the KDC will return them encrypted using that service's key. So in order for a service to decrypt those Kerberos tickets, it also needs some way to know the key associated with its own service principal.

    Often, the service key is generated randomly and provided through a "keytab" file. However, in Active Directory systems, most service accounts are regular user accounts which have a password – so their key can be derived from the service's password instead.

    It seems that your SPNEGO module supports both methods (see lines 150-160) – it can be given a keytab or a password.

    In any case, the setting has absolutely nothing to do with the clients that will be connecting to your service. It only establishes the server's own identity.

    What's the exact use of the SPN in the Kerberos scenario?

    It's similar to the domain name field in HTTPS certificates. For example, when a browser performs Kerberos authentication to https://example.com, it will always request a Kerberos ticket for the SPN HTTP/example.com from the KDC.

    If you're familiar with OAuth2 or SAML or JWTs, I believe the Kerberos SPN would be the rough equivalent of the "audience" field in SAML assertions, or the "aud" field in JWTs.

    (Note that the browser only knows your service by its SPN, and doesn't care about the actual service accounts that are used behind the scenes – e.g. Active Directory happens to map SPNs to real "user" accounts in this case, but other Kerberos implementations do it differently)

    Do I have to use the same user in both web.xml and setspn command?

    Yes, it needs to be the same user, because the service must be able to decrypt tickets that were issued for its SPN, so it needs to know the same symmetric key.

    And which user to choose?

    Create a new, dedicated account just for that service. Do not use a real "person" account.

    Use a long, highly random password, and mark it as non-expiring. Additionally, make sure to enable both "Account supports Kerberos AES xxx-bit" features in the account's options (assuming your Java SPNEGO thing supports AES, which it really ought to).

    Do I have to execute the command setspn in every windows computer or there is a way to do it just once?

    No, it doesn't matter where you execute it, because it only edits the actual account on the domain controllers – it leaves no trace on the local machine. (Specifically, it sets the servicePrincipalName LDAP attribute for the provided account.)

    Clients only recognize your service by its SPN, and they have no need to know about the account mapping that's done by the KDC behind the scenes.