Adding Kerberos MtM Authentication

Overview

As Kerberos is an authentication protocol rather than an implementation, this section is more of a general guide than concrete instructions. However, we outline what parts of Atoti Limits you need to configure to use Kerberos for machine-to-machine (MtM) authentication with a Key Distribution Center (KDC).

This guide only assumes that you have access to a keytab file containing a principal-user, who is the service user that will be used to authenticate the MtM requests. This guide does not assume anything else about your KDC.

As the MtM communication is bidirectional, Atoti Limits and your connected Atoti Server act as both a client and a server at different points in time. For this reason, we recommend placing the security configurations in a shared module that can be used by both (or potentially more) applications.

This guide consists of two sections. The first section shall outline from a high level the changes that need to be made. The second section shall outline where these changes should go in Atoti Limits. We will provide code samples throughout.

Kerberos Security Configuration

In general, the configuration required to use Kerberos authentication in Spring is made up of two parts:

  • Client configuration: the configuration required to authenticate the machine sending the request.
  • Server configuration: the configuration required to authenticate the machine receiving the request.

First, get the latest version of the Spring Security Kerberos dependencies:

<dependency>
  <groupId>org.springframework.security.kerberos</groupId>
  <artifactId>spring-security-kerberos-core</artifactId>
  <version>${spring-security-kerberos.version}</version>
</dependency>

<!-- used for the server configuration -->
<dependency>
<groupId>org.springframework.security.kerberos</groupId>
<artifactId>spring-security-kerberos-web</artifactId>
<version>${spring-security-kerberos.version}</version>
</dependency>

        <!-- used for the client configuration -->
<dependency>
<groupId>org.springframework.security.kerberos</groupId>
<artifactId>spring-security-kerberos-client</artifactId>
<version>${spring-security-kerberos.version}</version>
</dependency>

Next, you can add your configuration.

Client Configuration

When acting as a client, the machine sending the request needs to authenticate with the KDC. This can be done using a KerberosRestTemplate, configured with the following:

  • keytabLocation: the location of the keytab file that contains the user’s credentials
  • servicePrincipal: the principal of the “service” user making the request
KerberosRestTemplate

To use the KerberosRestTemplate, inject it into your service and use it to make requests.

Server Configuration

When acting as a server, the machine receiving the request needs to authenticate the user. For this, you need to implement the following components.

Kerberos Authentication providers

You need to specify the Kerberos authentication providers to give an authenticated ticket to the machine requesting authorization.

  • KerberosAuthenticationProvider: authenticates client requests.
  • KerberosServiceAuthenticationProvider: authenticates service requests.
KerberosAuthenticationProvider
KerberosServiceAuthenticationProvider

Authentication Manager

The authentication manager used by Spring needs to use the authentication providers. The standard approach is to inject them into the manager.

AuthenticationManager

The authentication entry point

When an unauthorized actor, in our case Atoti Limits or the connected server, makes a request, they are redirected to the authentication entry point. In many applications, this is in the form of a login page. For Kerberos, the SpnegoEntryPoint is used to redirect the user to the KDC.

note

You can use this entry point to redirect to a login page. We won’t cover that here, because we are focusing on machine-to-machine communication, but that is how to implement SSO using Kerberos.

SpnegoEntryPoint

The authentication filter

The SpnegoAuthenticationProcessingFilter is responsible for processing the authentication request. It authenticates the user once validated by the KDC and sets the Spring authentication for the rest of the request.

SpnegoAuthenticationProcessingFilter

The filter chain

This is where all of the above is put together. It is your responsibility to define your filter chains. This is because the filter chain contains endpoints and user roles related to your organization, including potentially other systems that are not part of Atoti Limits.

The following considerations must be made for defining the Kerberos filter chain:

  • Redirect unauthorized requests to the SpnegoEntryPoint.
  • Add the SpnegoAuthenticationProcessingFilter to the filter chain to set the Authorization Negotiate xxx header.
  • Make sure the request matchers are loose enough to allow any access to vital assets to happen, such as a login page, but strict enough that private assets require authentication, for example, sensitive endpoints.

A simple filter chain for Kerberos looks like this:


@Bean
public SecurityFilterChain filterChain(final HttpSecurity http, SpnegoEntryPoint spnegoEntryPoint,
        SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter)
        throws Exception {
  return http
          .exceptionHandling(exception -> exception.authenticationEntryPoint(spnegoEntryPoint))
          .authorizeHttpRequests(auth -> auth
                  // we require that all endpoints are authentication
                  .anyRequest().authenticated())
          .addFilterBefore(spnegoAuthenticationProcessingFilter, BasicAuthenticationFilter.class)
          .build();
}

The UserDetailsService

The UserDetailsService, which usually fetches our user roles, is used only for the service user here. Note that if you want to impose user roles for your service user, this is the place to do it. As an example only, to replicate the default admin user that is shipped with Atoti Limits you can use the following:

UserDetailsService

note

This serviceUserDetailsService is not exposed as a Spring Bean, to avoid conflicts with other UserDetailsService beans that may be present in your application.

tip

As mentioned above, we recommend placing all of the above in a shared module that can be used by both Atoti Limits and your connected Atoti Server.

Kerberos in Atoti Limits

Once you have prepared your security configuration, you can use it in Atoti Limits and your connected server.

Import the security configuration

Import your security configuration created in the previous section into both Atoti Limits and your connected server.

warning

It is up to you to determine if your security can be imported alongside your current security configuration, or if it should replace any existing configurations. This is because security configurations are architecture-specific, and so they differ from client to client.

Implement the required rest clients

As discussed in Adding Custom Machine-to-Machine (MtM) Authentication, when customizing authentication, users need to implement the following interfaces:

  1. ILimitsRestTemplateProvider in the connected server for Atoti Server version 6.0.x or
  2. ILimitsRestClientProvider in the connected server, for Atoti Server version 6.1.x or 6.0.x-sb3
  3. ILimitsRestClientBuilderProvider in Atoti Limits

1. ILimitsRestTemplateProvider

In this case you only need to expose the KerberosRestTemplate that you created in the previous section.

2. ILimitsRestClientProvider

There is no spring-security-kerberos implementation at this time of a “Kerberos” RestClient like there is for KerberosRestTemplate. You can instantiate a RestClient with:

   RestTemplate template = new KerberosRestTemplate(...);
   RestClient restClient = RestClient.create(template);

However, the Kerberos authentication fails, because the RestTemplate itself does not manage the execution of the request.

This means you will need to implement your own version of ILimitsConnector to send the requests, which should be exposed in your connected server.

note

The API of ILimitsRestClientProvider provides a RestClient rather than a RestTemplate as it is the most modern Spring REST client. We expect the spring-security-kerberos project to eventually implement a KerberosRestClient.

A sample of the changes required for your ILimitsConnector is provided below.

KerberosLimitsConnector

3. ILimitsRestClientProvider

Similar to the RestClient, there is no implementation at this time of a “Kerberos” RestClient.Builder. In this case, it means you have to provide an implementation of IWebClientService in Atoti Limits. We have provided KerberosWebClientService as an example.

KerberosWebClientService

Further Resources

Please see the following articles for further resources on integrating Kerberos with Spring: