Autenticacao

Todas as APIs da I-Systems utilizam o protocolo OAuth 2.0 para autenticacao. Esta pagina explica como obter e utilizar tokens de acesso para fazer chamadas as nossas APIs.

Ambientes Disponiveis

Importante: As credenciais sao especificas para cada ambiente. Certifique-se de usar as credenciais corretas para o ambiente desejado.
UAT

User Acceptance Testing

Ambiente para testes de aceitacao do usuario. Usado para validacao final antes da promocao para producao.

URL Base API:https://apim-isystems-uat-brzsth-001.ihstowers.com
Token URL:https://login.microsoftonline.com/ihstowers.onmicrosoft.com/oauth2/v2.0/token
Scope:https://ihstowers.onmicrosoft.com/apim-isystems-uat/.default
PRD

Producao

Ambiente de producao com dados reais. Use apenas apos validacao completa no ambiente de UAT.

URL Base API:https://apim-isystems-prd-brzsth-001.ihstowers.com
Token URL:https://login.microsoftonline.com/ihstowers.onmicrosoft.com/oauth2/v2.0/token
Scope:https://ihstowers.onmicrosoft.com/apim-isystems-prd/.default

Atencao: Credenciais por Ambiente

Cada ambiente possui suas proprias credenciais (client_id e client_secret). Uma credencial criada em UAT nao funcionara em PRD e vice-versa.

  • Solicite credenciais especificas para cada ambiente que precisar usar
  • Armazene as credenciais de forma organizada, identificando o ambiente
  • Nunca tente usar credenciais de um ambiente em outro
  • Credenciais de PRD devem ter controle de acesso ainda mais restrito

Fluxo de Autenticacao

Utilizamos o fluxo Client Credentials do OAuth 2.0, adequado para integracao server-to-server.

1

Obtenha suas Credenciais

Voce recebera:

  • client_id: Identificador unico da sua aplicacao
  • client_secret: Chave secreta (mantenha segura!)
  • token_url: URL do endpoint de autenticacao
2

Solicite um Token de Acesso

Faca uma requisicao POST para o endpoint de token:

3

Use o Token nas Chamadas API

Inclua o token no header Authorization de cada requisicao.

Exemplos de Codigo

Obtendo o Token de Acesso

Importante: O Token URL e o mesmo para todos os ambientes (Azure AD), mas o scope muda conforme o ambiente:
  • UAT: https://ihstowers.onmicrosoft.com/apim-isystems-uat/.default
  • PRD: https://ihstowers.onmicrosoft.com/apim-isystems-prd/.default

cURL

# Exemplo para ambiente de PRODUCAO
curl --location 'https://login.microsoftonline.com/ihstowers.onmicrosoft.com/oauth2/v2.0/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'client_id=<SEU_CLIENT_ID_PRD>' \
  --data-urlencode 'client_secret=<SEU_CLIENT_SECRET_PRD>' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'scope=https://ihstowers.onmicrosoft.com/apim-isystems-prd/.default'

# Exemplo para ambiente de UAT
curl --location 'https://login.microsoftonline.com/ihstowers.onmicrosoft.com/oauth2/v2.0/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'client_id=<SEU_CLIENT_ID_UAT>' \
  --data-urlencode 'client_secret=<SEU_CLIENT_SECRET_UAT>' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'scope=https://ihstowers.onmicrosoft.com/apim-isystems-uat/.default'

JavaScript (Node.js)

const axios = require('axios');

// Configure o ambiente desejado
const ENVIRONMENT = process.env.ENV || 'prd'; // uat ou prd

const TOKEN_URL = 'https://login.microsoftonline.com/ihstowers.onmicrosoft.com/oauth2/v2.0/token';

const SCOPES = {
  uat: 'https://ihstowers.onmicrosoft.com/apim-isystems-uat/.default',
  prd: 'https://ihstowers.onmicrosoft.com/apim-isystems-prd/.default'
};

async function getAccessToken(environment = ENVIRONMENT) {
  const params = new URLSearchParams();
  params.append('grant_type', 'client_credentials');
  params.append('client_id', process.env[`CLIENT_ID_${environment.toUpperCase()}`]);
  params.append('client_secret', process.env[`CLIENT_SECRET_${environment.toUpperCase()}`]);
  params.append('scope', SCOPES[environment]);

  try {
    const response = await axios.post(TOKEN_URL, params, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    });

    return response.data.access_token;
  } catch (error) {
    console.error(`Erro ao obter token no ambiente ${environment}:`, error);
    throw error;
  }
}

// Uso
const token = await getAccessToken('uat'); // ou 'prd'
console.log('Token obtido:', token);

Python

import requests
import os

# Configure o ambiente desejado
ENVIRONMENT = os.environ.get("ENV", "prd")  # uat ou prd

TOKEN_URL = "https://login.microsoftonline.com/ihstowers.onmicrosoft.com/oauth2/v2.0/token"

SCOPES = {
    "uat": "https://ihstowers.onmicrosoft.com/apim-isystems-uat/.default",
    "prd": "https://ihstowers.onmicrosoft.com/apim-isystems-prd/.default"
}

def get_access_token(environment=ENVIRONMENT):
    payload = {
        "grant_type": "client_credentials",
        "client_id": os.environ.get(f"CLIENT_ID_{environment.upper()}"),
        "client_secret": os.environ.get(f"CLIENT_SECRET_{environment.upper()}"),
        "scope": SCOPES[environment]
    }

    headers = {
        "Content-Type": "application/x-www-form-urlencoded"
    }

    response = requests.post(TOKEN_URL, data=payload, headers=headers)
    response.raise_for_status()

    return response.json()["access_token"]

# Uso
token = get_access_token("uat")  # ou 'prd'
print(f"Token obtido: {token}")

Java

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.Map;

public class AuthClient {
    private static final String TOKEN_URL =
        "https://login.microsoftonline.com/ihstowers.onmicrosoft.com/oauth2/v2.0/token";

    private static final Map<String, String> SCOPES = Map.of(
        "uat", "https://ihstowers.onmicrosoft.com/apim-isystems-uat/.default",
        "prd", "https://ihstowers.onmicrosoft.com/apim-isystems-prd/.default"
    );

    public static String getAccessToken(String environment, String clientId,
                                       String clientSecret) throws Exception {
        String scope = SCOPES.get(environment);

        String body = String.format(
            "grant_type=client_credentials&client_id=%s&client_secret=%s&scope=%s",
            URLEncoder.encode(clientId, StandardCharsets.UTF_8),
            URLEncoder.encode(clientSecret, StandardCharsets.UTF_8),
            URLEncoder.encode(scope, StandardCharsets.UTF_8)
        );

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(TOKEN_URL))
            .header("Content-Type", "application/x-www-form-urlencoded")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();

        HttpResponse<String> response = client.send(
            request,
            HttpResponse.BodyHandlers.ofString()
        );

        JsonObject jsonResponse = JsonParser.parseString(response.body())
            .getAsJsonObject();

        return jsonResponse.get("access_token").getAsString();
    }

    // Uso
    public static void main(String[] args) throws Exception {
        String token = getAccessToken("uat", "CLIENT_ID_UAT", "CLIENT_SECRET_UAT");
        System.out.println("Token obtido: " + token);
    }
}

Resposta do Endpoint de Token

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "ext_expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWl..."
}
Campos da Resposta:
  • token_type: Tipo do token, sempre "Bearer"
  • expires_in: Tempo de validade em segundos (3599 = aproximadamente 1 hora)
  • ext_expires_in: Tempo de validade estendida em segundos (Azure AD)
  • access_token: Token JWT para usar nas chamadas API. Use este token no header Authorization

Usando o Token nas Chamadas API

Importante: Use a URL base do ambiente correspondente ao scope usado na autenticacao:
  • UAT: https://apim-isystems-uat-brzsth-001.ihstowers.com
  • PRD: https://apim-isystems-prd-brzsth-001.ihstowers.com

cURL

# Exemplo de chamada para o ambiente de PRODUCAO
curl --location 'https://apim-isystems-prd-brzsth-001.ihstowers.com/geographicAddressManagement/geographicAddress?postcode=24727118&streetNr=21' \
  --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWl...'

# Exemplo de chamada para o ambiente de UAT
curl --location 'https://apim-isystems-uat-brzsth-001.ihstowers.com/geographicAddressManagement/geographicAddress?postcode=24727118&streetNr=21' \
  --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWl...'

JavaScript (Node.js)

const axios = require('axios');

const API_BASE_URLS = {
  uat: 'https://apim-isystems-uat-brzsth-001.ihstowers.com',
  prd: 'https://apim-isystems-prd-brzsth-001.ihstowers.com'
};

async function callAPI(accessToken, environment = 'prd', params = {}) {
  const baseUrl = API_BASE_URLS[environment];
  const endpoint = '/geographicAddressManagement/geographicAddress';

  try {
    const response = await axios.get(`${baseUrl}${endpoint}`, {
      params: params,
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    });

    return response.data;
  } catch (error) {
    console.error(`Erro na chamada API (${environment}):`, error);
    throw error;
  }
}

// Uso
const token = await getAccessToken('uat');
const data = await callAPI(token, 'uat', {
  postcode: '24727118',
  streetNr: '21'
});
console.log('Dados recebidos:', data);

Python

import requests

API_BASE_URLS = {
    "uat": "https://apim-isystems-uat-brzsth-001.ihstowers.com",
    "prd": "https://apim-isystems-prd-brzsth-001.ihstowers.com"
}

def call_api(access_token, environment="prd", params=None):
    base_url = API_BASE_URLS[environment]
    endpoint = "/geographicAddressManagement/geographicAddress"
    url = f"{base_url}{endpoint}"

    headers = {
        "Authorization": f"Bearer {access_token}"
    }

    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()

    return response.json()

# Uso
token = get_access_token("uat")
data = call_api(token, "uat", params={
    "postcode": "24727118",
    "streetNr": "21"
})
print(f"Dados recebidos: {data}")

Java

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.Map;

public class ApiClient {
    private static final Map<String, String> API_BASE_URLS = Map.of(
        "uat", "https://apim-isystems-uat-brzsth-001.ihstowers.com",
        "prd", "https://apim-isystems-prd-brzsth-001.ihstowers.com"
    );

    public static String callAPI(String accessToken, String environment,
                                 String postcode, String streetNr)
            throws Exception {
        String baseUrl = API_BASE_URLS.get(environment);
        String endpoint = "/geographicAddressManagement/geographicAddress";
        String url = String.format("%s%s?postcode=%s&streetNr=%s",
            baseUrl, endpoint, postcode, streetNr);

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header("Authorization", "Bearer " + accessToken)
            .GET()
            .build();

        HttpResponse<String> response = client.send(
            request,
            HttpResponse.BodyHandlers.ofString()
        );

        return response.body();
    }

    // Uso
    public static void main(String[] args) throws Exception {
        String token = getAccessToken("uat", "CLIENT_ID_UAT", "CLIENT_SECRET_UAT");
        String data = callAPI(token, "uat", "24727118", "21");
        System.out.println("Dados recebidos: " + data);
    }
}

Boas Praticas de Seguranca

Nunca Exponha suas Credenciais

Nunca inclua client_id e client_secret diretamente no codigo. Use variaveis de ambiente ou gerenciadores de segredos.

Armazene Tokens com Seguranca

Tokens de acesso sao senhas temporarias. Armazene-os de forma segura e nunca os exponha em logs ou interfaces publicas.

Implemente Cache de Tokens

Tokens tem validade de 1 hora. Implemente cache para reutilizar tokens validos e evitar requisicoes desnecessarias.

Renove Tokens Expirados

Quando receber erro 401, solicite um novo token automaticamente. Implemente retry logic para lidar com expiracao.

Use HTTPS

Todas as comunicacoes devem usar HTTPS para garantir que credenciais e tokens sejam transmitidos de forma segura.

Rotacao de Credenciais

Implemente processos para rotacionar periodicamente suas credenciais, especialmente se houver suspeita de comprometimento.

Tratamento de Erros

Codigo HTTPErroDescricaoAcao
400Bad RequestParametros invalidos ou ausentesVerifique os parametros da requisicao
401UnauthorizedCredenciais invalidas ou token expiradoVerifique as credenciais ou solicite novo token
403ForbiddenToken valido mas sem permissoesVerifique os scopes necessarios
429Too Many RequestsLimite de taxa excedidoImplemente backoff e respeite rate limits
500Internal Server ErrorErro no servidorTente novamente mais tarde ou contate suporte

Proximo Passo

Agora que voce ja sabe como autenticar, aprenda a configurar notificacoes de callback para receber atualizacoes sobre suas operacoes.

Ir para Notificacao de Callback