Hi Artem,
I’ve prepared an example where the Client built with Jmix 2.5 accesses the Service built with Jmix 1.6: jmix-projects/jmix-restds-compatibility
The Service app (Jmix 1.6) exposes Customer
entity through the Generic REST.
The Client (Jmix 2.5) consumes the Service’s Customer
data using REST DataStore.
Jmix 1.x REST API supports only the Password grant, so the Client authenticates in the Service as a special “integration user”. This user is defined in the Service with minimal permissions required for the integration.
The Client app uses the standard restds_RestPasswordAuthenticator
, but custom RestTokenHolder
implementation that stores the token of the integration user:
package com.company.clientapp.security;
import io.jmix.restds.impl.RestTokenHolder;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Primary
@Component
public class IntegrationTokenHolder implements RestTokenHolder {
private String accessToken;
private String refreshToken;
@Override
public String getAccessToken() {
return accessToken;
}
@Override
public String getRefreshToken() {
return refreshToken;
}
@Override
public void setTokens(String accessToken, String refreshToken) {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
}
}
All Service invocations use the same token.
The IntegrationInitializer
class authenticates in the Service on the Client application start using the “integration user” credentials obtained from the environment:
integration.store=serviceapp
integration.user.username=integration
integration.user.password=integration
package com.company.clientapp.security;
import io.jmix.restds.impl.RestPasswordAuthenticator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class IntegrationInitializer {
@Value("${integration.store}")
private String integrationStore;
@Value("${integration.user}")
private String integrationUser;
@Value("${integration.password}")
private String integrationPassword;
@EventListener
public void onApplicationStarted(final ApplicationStartedEvent event) {
RestPasswordAuthenticator authenticator = event.getApplicationContext().getBean(RestPasswordAuthenticator.class);
authenticator.setDataStoreName(integrationStore);
authenticator.authenticate(integrationUser, integrationPassword);
}
}
Jmix 1.x uses non-standard path for obtaining tokens, so the Client includes the following property:
serviceapp.tokenPath=/oauth/token
The jmix.restds.authentication-provider-store
property that provides authentication of the current user in the service must not be present the environment.
Please let us know if you have any trouble with this approach.
Regards,
Konstantin