🇨🇳 Синхронизация данных пользователей DiscourseConnect с помощью sync_sso [Java] | Синхронизация данных пользователей DiscourseConnect с помощью sync_sso [Java]

Недавно возникла задача синхронизации существующих пользователей в Discourse с помощью SSO.

Поэтому я реализовал решение на Java, основываясь на официальном примере для PHP (Sync DiscourseConnect user data with the sync_sso route - developers - Discourse Meta).

Реализация довольно проста, но требует использования дополнительных библиотек, прежде всего Apache Commons Codec и OkHttp.

Apache Commons Codec используется для создания цифровой подписи, а OkHttp — для отправки HTTP POST-запросов.

Настройка параметров

Заранее необходимо получить 4 параметра.

Способ получения этих четырёх параметров описан в статье: Discourse 使用 DiscourseConnect 来进行用户数据同步

const apiKey = '4fe83002bb5fba8c9a61a65e5b4b0a3cf8233b0e4ccafc85ebd6607abab4651a';
const apiUser = 'system';
const connectSecret = 'jdhb19*Xh3!nu(#k';

Настройка параметров SSO

Настройка параметров аналогична параметрам GET-запроса в URL.

Наш код на Java выглядит следующим образом:

            URIBuilder builder = new URIBuilder();
            builder.addParameter("external_id", "1");
            builder.addParameter("email", "info@isharkfly.com");
            builder.addParameter("username", "info.visafn.sso");
            builder.addParameter("add_groups", "bar");
            builder.addParameter("require_activation", "false");
             url = StringUtils.removeStart(builder.build().toString(),"?");
            System.out.println(StringUtils.removeStart(url, "?"));

Base64 и цифровая подпись

После получения строки URL выше необходимо выполнить два следующих шага.

Первый шаг — преобразование полученного URL в формат Base64.

Второй шаг — создание цифровой подписи для полученной строки Base64 с использованием алгоритма HMAC_SHA_256.

При этом ключ, полученный на первом шаге, должен быть передан в качестве параметра для участия в вычислениях вместе с алгоритмом.

        String sso= "admin/users/sync_sso";
        String sig= new HmacUtils(HmacAlgorithms.HMAC_SHA_256, "55619458534897").hmacHex(ssoPayload);

После получения этих двух значений необходимо сформировать новую структуру данных в формате JSON.

Структура данных будет выглядеть примерно так, и она будет использоваться в качестве тела POST-запроса:

{
    "sso": "P2V4dGVybmFsX2lkPTEmZW1haWw9aW5mbyU0MHZpc2Fmbi5jb20mdXNlcm5hbWU9aW5mby52aXNhZm4mcmVxdWlyZV9hY3RpdmF0aW9uPXRydWU=",
    "sig": "403a205a004e37ffab2bf77cc12b2eac352d71820983706d86984eec9821a0c4"
}

Отправка POST-запроса

Можно использовать любой инструмент, поддерживающий HTTP.

Поскольку в Java чаще всего используется OkHttp, мы будем использовать его для отправки запроса.

private OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(
                    MediaType.parse("application/json"), objectMapper.writeValueAsString(syncSSO));
            Response response = client.newCall(postRequest(path, body)).execute();

Метод postRequest, упомянутый выше, используется для формирования запроса с помощью имеющихся параметров.

Вот как он написан:

    public Request postRequest(String path, RequestBody body) {
        HttpUrl.Builder urlBuilder = HttpUrl.parse(site_url + path).newBuilder();
        Request request = new Request.Builder().url(urlBuilder.build().toString())
                .addHeader("api-username", api_username)
                .addHeader("api-key", api_key)
                .post(body)
                .build();
        return request;
    }

Если всё настроено правильно, приведённый выше код позволит успешно выполнить синхронизацию данных SSO.