Atoti Sign-Off communicates with the application server via a REST API. HTTP clients are used to send the REST requests. The Spring
RestClient is the default HTTP client used.
Default Behavior
By default, the REST requests are authenticated using a JWT token that is generated by the
IJwtService. Users can customize this authentication mechanism to
use a different method, such as Basic Authentication.
Configuring the Requests
We ship two different clients to communicate with the application server, one that uses JWT authentication and one that uses Basic authentication. The JWT
client is used by default via the property sign-off.application.authentication-mode=jwt, but you can switch to the Basic client by setting the property sign-off.application.authentication-mode=basic.
Customizing the Requests
To customize the REST requests you need to implement your own implementation of the ISignOffRestClientBuilder interface:
ISignOffRestClientBuilder
/**
* <b>ISignOffRestClientBuilder</b>
*
* <p>Used to provide {@link RestClient.Builder} instances for building and sending authenticated requests to Atoti servers connected to Sign-Off.
* This allows for the creation of {@link RestClient} instances with specific configurations for each server, for example, to handle URLS, authentication or custom headers.
*
* @author ActiveViam
*/publicinterfaceISignOffRestClientBuilder{/**
* Get a {@link RestClient.Builder} for the specified server name.
*
* @param serverName the name of the server for which to get the {@link RestClient.Builder}.
* @return a {@link RestClient.Builder} configured for the specified server.
*/ RestClient.BuildergetRestClientBuilder(String serverName);}
For more information on creating a custom RestClient.Builder, refer to
the Spring documentation. Alternatively, you can check
out SignOffJwtAuthRestClientBuilder or SignOffBasicAuthRestClientBuilder to see how we implemented the default clients.
SignOffJwtAuthRestClientBuilder
/**
* <b>SignOffJwtAuthRestClientBuilder</b>
* <p> Used to provide {@link RestClient.Builder} instances for building and sending JWT authenticated requests to Atoti servers connected to Sign-Off.
*
* @author ActiveViam
*/@RequiredArgsConstructorpublicclassSignOffJwtAuthRestClientBuilderimplements ISignOffRestClientBuilder {protectedfinal IRestApiConfiguration restApiConfiguration;protectedfinal IJwtService jwtService;protectedfinal UserDetailsService userDetailsService;protected Map<String, RestClient.Builder> restClientBuilders =new HashMap<>();@PostConstructpublicvoidinit(){ restApiConfiguration.getServers().forEach(server ->{ restClientBuilders.put(server, buildJwtRestClientBuilder(server));});}private RestClient.BuilderbuildJwtRestClientBuilder(String server){ String servicePrincipal = restApiConfiguration.getUser(server); Collection<String> authorities = userDetailsService.loadUserByUsername(servicePrincipal).getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet()); String jwt = jwtService.getToken(servicePrincipal, authorities);return RestClient.builder().baseUrl(restApiConfiguration.getUrl(server).toString()).defaultHeader(AUTHORIZATION,"Jwt "+ jwt);}@Overridepublic RestClient.BuildergetRestClientBuilder(String serverName){return restClientBuilders.get(serverName);}}
SignOffBasicAuthRestClientBuilder
/**
* <b>SignOffBasicAuthRestClientBuilder</b>
* <p> Used to provide {@link RestClient.Builder} instances for building and sending Basic authenticated requests to Atoti servers connected to Sign-Off.
*
* @author ActiveViam
*/@RequiredArgsConstructorpublicclassSignOffBasicAuthRestClientBuilderimplements ISignOffRestClientBuilder {protectedfinal IRestApiConfiguration restApiConfiguration;protected Map<String, RestClient.Builder> restClientBuilders =new HashMap<>();// This cookie spec is used by the application servers (MR/FRTB etc.). If the RestTemplates are not configured to expect this,
// a WARN log is generated with every response
protectedstaticfinal HttpClient STANDARD_COOKIE_CLIENT = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(StandardCookieSpec.RELAXED).build()).build();@PostConstructpublicvoidinit(){ restApiConfiguration.getServers().forEach(server ->{ RestClient.Builder restClientBuilder = RestClient.builder().defaultHeaders(headers -> headers.setBasicAuth(restApiConfiguration.getUser(server), restApiConfiguration.getPassword(server))).baseUrl(restApiConfiguration.getUrl(server).toString()).requestFactory(new HttpComponentsClientHttpRequestFactory(STANDARD_COOKIE_CLIENT)); restClientBuilders.put(server, restClientBuilder);});}@Overridepublic RestClient.BuildergetRestClientBuilder(String serverName){return restClientBuilders.get(serverName);}}