Configuration

Several administrative tasks should be performed regularly while working with Mobile Utility Server to keep the published content up-to-date.

Network

The context path /admin for administrative purposes is authenticated, but it should be exposed only in trusted networks.

Creating First Admin User

When calling admin APIs provided by the Mobile Utility Server, basic HTTP authentication is required. This why we need to add users and their passwords in the database.

The first user we need to add is basically the main admin user, let’s call the user system-admin. The first user needs to be inserted in the database.

First, we need to generate the password via openssl:

openssl rand -base64 12

Output will look like this:

DH4v3SCoDRDUAFBD

In order to store the password in the database, we need to encode it using bcrypt first. You can use the htpasswd command to achieve this:

htpasswd -bnBC 12 "" DH4v3SCoDRDUAFBD | tr -d ':'

Output will look like this:

$2y$12$GM/J9uvNy1W.eSy1mB2HB.xk2uLYtnjcD3rUEkqPkVCL43b0F9xa.

You can now put this all together and store the user in the database:

INSERT INTO mus_user (id, username, password, enabled)
VALUES (nextval('mus_user_seq'), 'system-admin', '$2y$12$GM/J9uvNy1W.eSy1mB2HB.xk2uLYtnjcD3rUEkqPkVCL43b0F9xa.', true);

INSERT INTO mus_user_authority (id, user_id, authority)
VALUES (nextval('mus_user_authority_seq'), (SELECT id FROM mus_user WHERE username = 'system-admin'), 'ROLE_ADMIN');
  • We stored the hashed password for the system-admin user.
  • We used authority ROLE_ADMIN for the administrator user who can call services published under /admin context. Regular users who only need to call registration and operation APIs can use a restricted ROLE_USER authority.

You can now check the changes in the database:

  • mus_user - New user record with the bcrypt-hashed password.
  • mus_user_authority - New user authority record.

At this point, you can open http://localhost:8080/admin/apps and use system-admin as username and DH4v3SCoDRDUAFBD, your password value respectively (plaintext) as the password.

Adding New Mobile Application

You can easily add a new mobile application by running the following API call:

curl --request POST \
  --url http://localhost:8080/admin/apps \
  --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
  --json '{
  "name": "mobile-app",
  "displayName": "My Mobile App"
}'

Adding New Certificate

Whenever your TLS/SSL certificate is about to expire, you need to add a new replacement certificate and associated fingerprint into the database.

There are several ways to add a new certificate.

Fetching Certificate Based on Domain

You can let our systems do the heavy lifting and fetch the SSL certificate automatically:

curl --request POST \
  --url http://localhost:8080/admin/apps/mobile-app/certificates/auto \
  --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
  --json '{
  "domain": "google.com"
}'

Importing Certificate in PEM Format

You can push PEM file to our systems. You can typically obtain a PEM format from the certificate vendor, or you can fetch it from a domain using openssl command:

openssl s_client -connect google.com:443 -servername google.com  2>/dev/null </dev/null |  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

Call the following service to import the certificate (notice the \n symbols in the certificate string):

curl --request POST \
  --url http://localhost:8080/admin/apps/mobile-app/certificates/pem \
  --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
  --json '{
  "domain": "google.com",
  "pem": "-----BEGIN CERTIFICATE-----\nMIIOOzCCDSOgAwIBAgIRAOtktS1T8xbLEmgT/IaWpuEwDQYJKoZIhvcNAQELBQAw\nRjELMAkGA1UEBhMCVVMxIjAgBgNVBAoTGUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBM\nTEMxEzARBgNVBAMTCkdUUyBDQSAxQzMwHhcNMjMwMjA4MDQzNDMwWhcNMjMwNTAz\nMDQzNDI5WjAXMRUwEwYDVQQDDAwqLmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggq\nhkjOPQMBBwNCAATt1Q07sURF52V6U8ASJ0JPgIwyErLwD36WUnuHZDU8MCaNtrEO\nyPo9zVlTttTx6lUQQ7fm9PMxKANBXF3C4G8Xo4IMHDCCDBgwDgYDVR0PAQH/BAQD\nAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYE\nFDRGztOLSrVak9gBPXmAgIEk8vQgMB8GA1UdIwQYMBaAFIp0f6+Fze6VzT2c0OJG\nFPNxNR0nMGoGCCsGAQUFBwEBBF4wXDAnBggrBgEFBQcwAYYbaHR0cDovL29jc3Au\ncGtpLmdvb2cvZ3RzMWMzMDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVw\nby9jZXJ0cy9ndHMxYzMuZGVyMIIJzQYDVR0RBIIJxDCCCcCCDCouZ29vZ2xlLmNv\nbYIWKi5hcHBlbmdpbmUuZ29vZ2xlLmNvbYIJKi5iZG4uZGV2ghUqLm9yaWdpbi10\nZXN0LmJkbi5kZXaCEiouY2xvdWQuZ29vZ2xlLmNvbYIYKi5jcm93ZHNvdXJjZS5n\nb29nbGUuY29tghgqLmRhdGFjb21wdXRlLmdvb2dsZS5jb22CCyouZ29vZ2xlLmNh\nggsqLmdvb2dsZS5jbIIOKi5nb29nbGUuY28uaW6CDiouZ29vZ2xlLmNvLmpwgg4q\nLmdvb2dsZS5jby51a4IPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWC\nDyouZ29vZ2xlLmNvbS5icoIPKi5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20u\nbXiCDyouZ29vZ2xlLmNvbS50coIPKi5nb29nbGUuY29tLnZuggsqLmdvb2dsZS5k\nZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZyggsqLmdvb2dsZS5odYILKi5nb29n\nbGUuaXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5wbIILKi5nb29nbGUucHSCEiou\nZ29vZ2xlYWRhcGlzLmNvbYIPKi5nb29nbGVhcGlzLmNughEqLmdvb2dsZXZpZGVv\nLmNvbYIMKi5nc3RhdGljLmNughAqLmdzdGF0aWMtY24uY29tgg9nb29nbGVjbmFw\ncHMuY26CESouZ29vZ2xlY25hcHBzLmNughFnb29nbGVhcHBzLWNuLmNvbYITKi5n\nb29nbGVhcHBzLWNuLmNvbYIMZ2tlY25hcHBzLmNugg4qLmdrZWNuYXBwcy5jboIS\nZ29vZ2xlZG93bmxvYWRzLmNughQqLmdvb2dsZWRvd25sb2Fkcy5jboIQcmVjYXB0\nY2hhLm5ldC5jboISKi5yZWNhcHRjaGEubmV0LmNughByZWNhcHRjaGEtY24ubmV0\nghIqLnJlY2FwdGNoYS1jbi5uZXSCC3dpZGV2aW5lLmNugg0qLndpZGV2aW5lLmNu\nghFhbXBwcm9qZWN0Lm9yZy5jboITKi5hbXBwcm9qZWN0Lm9yZy5jboIRYW1wcHJv\namVjdC5uZXQuY26CEyouYW1wcHJvamVjdC5uZXQuY26CF2dvb2dsZS1hbmFseXRp\nY3MtY24uY29tghkqLmdvb2dsZS1hbmFseXRpY3MtY24uY29tghdnb29nbGVhZHNl\ncnZpY2VzLWNuLmNvbYIZKi5nb29nbGVhZHNlcnZpY2VzLWNuLmNvbYIRZ29vZ2xl\ndmFkcy1jbi5jb22CEyouZ29vZ2xldmFkcy1jbi5jb22CEWdvb2dsZWFwaXMtY24u\nY29tghMqLmdvb2dsZWFwaXMtY24uY29tghVnb29nbGVvcHRpbWl6ZS1jbi5jb22C\nFyouZ29vZ2xlb3B0aW1pemUtY24uY29tghJkb3VibGVjbGljay1jbi5uZXSCFCou\nZG91YmxlY2xpY2stY24ubmV0ghgqLmZscy5kb3VibGVjbGljay1jbi5uZXSCFiou\nZy5kb3VibGVjbGljay1jbi5uZXSCDmRvdWJsZWNsaWNrLmNughAqLmRvdWJsZWNs\naWNrLmNughQqLmZscy5kb3VibGVjbGljay5jboISKi5nLmRvdWJsZWNsaWNrLmNu\nghFkYXJ0c2VhcmNoLWNuLm5ldIITKi5kYXJ0c2VhcmNoLWNuLm5ldIIdZ29vZ2xl\ndHJhdmVsYWRzZXJ2aWNlcy1jbi5jb22CHyouZ29vZ2xldHJhdmVsYWRzZXJ2aWNl\ncy1jbi5jb22CGGdvb2dsZXRhZ3NlcnZpY2VzLWNuLmNvbYIaKi5nb29nbGV0YWdz\nZXJ2aWNlcy1jbi5jb22CF2dvb2dsZXRhZ21hbmFnZXItY24uY29tghkqLmdvb2ds\nZXRhZ21hbmFnZXItY24uY29tghhnb29nbGVzeW5kaWNhdGlvbi1jbi5jb22CGiou\nZ29vZ2xlc3luZGljYXRpb24tY24uY29tgiQqLnNhZmVmcmFtZS5nb29nbGVzeW5k\naWNhdGlvbi1jbi5jb22CFmFwcC1tZWFzdXJlbWVudC1jbi5jb22CGCouYXBwLW1l\nYXN1cmVtZW50LWNuLmNvbYILZ3Z0MS1jbi5jb22CDSouZ3Z0MS1jbi5jb22CC2d2\ndDItY24uY29tgg0qLmd2dDItY24uY29tggsybWRuLWNuLm5ldIINKi4ybWRuLWNu\nLm5ldIIUZ29vZ2xlZmxpZ2h0cy1jbi5uZXSCFiouZ29vZ2xlZmxpZ2h0cy1jbi5u\nZXSCDGFkbW9iLWNuLmNvbYIOKi5hZG1vYi1jbi5jb22CFGdvb2dsZXNhbmRib3gt\nY24uY29tghYqLmdvb2dsZXNhbmRib3gtY24uY29tgh4qLnNhZmVudXAuZ29vZ2xl\nc2FuZGJveC1jbi5jb22CDSouZ3N0YXRpYy5jb22CFCoubWV0cmljLmdzdGF0aWMu\nY29tggoqLmd2dDEuY29tghEqLmdjcGNkbi5ndnQxLmNvbYIKKi5ndnQyLmNvbYIO\nKi5nY3AuZ3Z0Mi5jb22CECoudXJsLmdvb2dsZS5jb22CFioueW91dHViZS1ub2Nv\nb2tpZS5jb22CCyoueXRpbWcuY29tggthbmRyb2lkLmNvbYINKi5hbmRyb2lkLmNv\nbYITKi5mbGFzaC5hbmRyb2lkLmNvbYIEZy5jboIGKi5nLmNuggRnLmNvggYqLmcu\nY2+CBmdvby5nbIIKd3d3Lmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5jb22CFiou\nZ29vZ2xlLWFuYWx5dGljcy5jb22CCmdvb2dsZS5jb22CEmdvb2dsZWNvbW1lcmNl\nLmNvbYIUKi5nb29nbGVjb21tZXJjZS5jb22CCGdncGh0LmNuggoqLmdncGh0LmNu\nggp1cmNoaW4uY29tggwqLnVyY2hpbi5jb22CCHlvdXR1LmJlggt5b3V0dWJlLmNv\nbYINKi55b3V0dWJlLmNvbYIUeW91dHViZWVkdWNhdGlvbi5jb22CFioueW91dHVi\nZWVkdWNhdGlvbi5jb22CD3lvdXR1YmVraWRzLmNvbYIRKi55b3V0dWJla2lkcy5j\nb22CBXl0LmJlggcqLnl0LmJlghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYIb\nZGV2ZWxvcGVyLmFuZHJvaWQuZ29vZ2xlLmNughxkZXZlbG9wZXJzLmFuZHJvaWQu\nZ29vZ2xlLmNughhzb3VyY2UuYW5kcm9pZC5nb29nbGUuY24wIQYDVR0gBBowGDAI\nBgZngQwBAgEwDAYKKwYBBAHWeQIFAzA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8v\nY3Jscy5wa2kuZ29vZy9ndHMxYzMvZlZKeGJWLUt0bWsuY3JsMIIBAwYKKwYBBAHW\neQIEAgSB9ASB8QDvAHUA6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4A\nAAGGL4TTZQAABAMARjBEAiBswmmK4qfRedFn3UOA/0R2GB0QDLT1Q3fQxshN0EQU\nMQIgZp8jeEdbzesoPEAauUhycH4tisuH5jxYbBIVV/bzZ1MAdgCzc3cH4YRQ+GOG\n1gWp3BEJSnktsWcMC4fc8AMOeTalmgAAAYYvhNN6AAAEAwBHMEUCIAS3+QtyIe7e\nqJ3MaZ06WKSOiP5oL6q0JYTH11C60kakAiEA38nXUV9Irb6fmWN2fQlLA4DUMNsO\nvRugCpNY6+H+dwMwDQYJKoZIhvcNAQELBQADggEBAKSUlwf6bi/1PYLTpTmW7F8v\nk+vp2SO1rbhgCYeoz9nfZbmfROGRYw2mmlC9anePCTQFbNkbiozeHs/cUBI4pm6D\nZy8aMDhh7ZbOA0/4ZoHXoAq/WElI8vz1g/uZ5DII8MPsSxwwe0eU8jKPzBN5mN0g\n0ObRYnTFK3odJsj5A7AX/29RaeYOX0gSWv/KeK2Z8ov3UQSBAEqbkDkznsP75n7H\nfl04q0D/QxxG+wKsf+ZsTb6ILBvcDQcnAjvjfQl+AVeCBnZTtwn0vLsgYzniBoRk\nwCItyBscNhKgLc7C8Ho1RLa/lfeW8lOGQN5ONUEuW2v6P5d9w2rLGYgSeDAIcsw=\n-----END CERTIFICATE-----"
}'

Force Update

Sometimes it is needed to suggest (or even to force) the client to update the mobile application version. It is a part of the response from Get App Fingerprints.

The rules are store in the database table mus_mobile_app_version.

The logic is lenient, returning OK even if the application version is not configured. Otherwise, compare the given application version (respecting the platform) to configured suggested or required version.

Let’s say, we have an application name my-testing-app in current version 3.5.0 and want to suggest clients to update when they have version lower than or equal to 3.3.0. Moreover, we want to force update when the version is lower than or equal to 3.1.0. Configuration major_os_version=null means that the rule applies for all operation system versions of the given platform. The following configuration force update of application version 2.9.0 because it is lower than the suggested 3.3.0 and even lower than the required 3.1.1.

insert into mus_mobile_app_version(id, app_id, platform, suggested_version, required_version, major_os_version, message_key)
values (nextval('mus_mobile_app_version_seq'), 1, 'IOS', '3.3.0', '3.1.0', null, 'my-testing-app.message-key');

In may happen, that it is not possible to update to the new version, because it is using newer API not available in the older operation system. In that case, configure a rule for the specific operation system major version (For iOS e.g. 12.4.2 it is 12. For Android, it is API level e.g. 29), which overrides the generic one. The following configuration return OK for application version 2.9.0 if the operation system version is 11.x.x.

insert into mus_mobile_app_version(id, app_id, platform, suggested_version, required_version, major_os_version, message_key)
values (nextval('mus_mobile_app_version_seq'), 1, 'IOS', '2.7.0', '1.9.0', 11, 'my-testing-app.message-key');

The feature is enabled by default. For performance optimization you may disable it by setting mobile-utility-server.features.version-verification.enabled=false

Force Update REST Administration

You may administrate force update feature via REST.

Localized Texts

To insert a localized text:

curl --request POST \
  --url http://localhost:8080/admin/texts \
  --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
  --json '{
  "messageKey": "required-app.internet-banking",
  "language": "en",
  "text": "Upgrade is required to make internet banking working."
}'

Application Versions

To insert an application version:

curl --request POST \
  --url http://localhost:8080/admin/apps/mobile-app/versions \
  --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
  --json '{
  "majorOsVersion": 11,
  "platform": "IOS",
  "suggestedVersion": "3.2.1",
  "requiredVersion": "2.9.8",
  "messageKey": "required-app.internet-banking"
}'

Monitoring and Observability

The WAR file includes the micrometer-registry-prometheus dependency. Discuss its configuration with the Spring Boot documentation.

Last updated on Dec 21, 2023 (09:13) Edit on Github Send Feedback
Search

develop

Mobile Utility Server