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 credentialsservicePrincipal
: the principal of the “service” user making the request
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.
Authentication Manager
The authentication manager used by Spring needs to use the authentication providers. The standard approach is to inject them into the manager.
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.
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.
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 theAuthorization 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:
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:
ILimitsRestTemplateProvider
in the connected server for Atoti Server version6.0.x
orILimitsRestClientProvider
in the connected server, for Atoti Server version6.1.x
or6.0.x-sb3
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.
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.
Further Resources
Please see the following articles for further resources on integrating Kerberos with Spring:
- Spring Security Kerberos
- Spring Security Kerberos examples
- Spring Security Kerberos Integration with MiniKdc
- SPNEGO/Kerberos Authentication in Spring