Recentemente, surgiu a necessidade de sincronizar usuários existentes com o Discourse usando SSO.
Portanto, com base na implementação oficial para PHP (Sync DiscourseConnect user data with the sync_sso route - developers - Discourse Meta), escrevi uma implementação em Java.
O método de implementação é simples, mas requer o uso de alguns pacotes adicionais, principalmente Apache commons codec e Okhttp.
Apache commons codec é usado para gerar assinaturas digitais, e Okhttp é usado para enviar requisições Http Post.
Configuração de Parâmetros Relacionados
Aqui estão 4 parâmetros que precisam ser obtidos com antecedência.
Para obter os 4 parâmetros abaixo, consulte o artigo: Discourse usa DiscourseConnect para sincronização de dados do usuário
const apiKey = '4fe83002bb5fba8c9a61a65e5b4b0a3cf8233b0e4ccafc85ebd6607abab4651a';
const apiUser = 'system';
const connectSecret = 'jdhb19*Xh3!nu(#k';
Configuração de Parâmetros SSO
A configuração dos parâmetros refere-se à configuração dos parâmetros do método GET da URL.
Nosso código 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 e Assinatura Digital
Depois de obter a string da URL acima, temos 2 etapas a seguir.
A primeira etapa é converter a URL obtida para Base64.
A segunda etapa é assinar digitalmente a string Base64 obtida após a conversão. O algoritmo HMAC_SHA_256 é usado para a assinatura.
Ao mesmo tempo, a chave obtida na primeira etapa é usada como parâmetro para participar do cálculo junto com o algoritmo.
String sso= "admin/users/sync_sso";
String sig= new HmacUtils(HmacAlgorithms.HMAC_SHA_256, "55619458534897").hmacHex(ssoPayload);
Depois de obter os 2 valores acima, reconstrua uma estrutura de dados JSON.
Uma estrutura de dados semelhante à seguinte é usada como dados do parâmetro Post:
{
"sso": "P2V4dGVybmFsX2lkPTEmZW1haWw9aW5mbyU0MHZpc2Fmbi5jb20mdXNlcm5hbWU9aW5mby52aXNhZm4mcmVxdWlyZV9hY3RpdmF0aW9uPXRydWU=",
"sig": "403a205a004e37ffab2bf77cc12b2eac352d71820983706d86984eec9821a0c4"
}
Envio de Requisição POST
Qualquer ferramenta que suporte HTTP pode ser usada.
Como OkHttp é amplamente utilizado em Java atualmente, usaremos OkHttp para enviar a requisição.
private OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(
MediaType.parse("application/json"), objectMapper.writeValueAsString(syncSSO));
Response response = client.newCall(postRequest(path, body)).execute();
O postRequest acima é um método no qual construímos a requisição usando os parâmetros existentes.
O método é escrito da seguinte forma:
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;
}
Se não houver problemas, o código acima poderá concluir a chamada de sincronização de dados SSO.