# Redireccionamento para o Localizador de Evidência

Após receber os dados e pedido do cidadão, o portal de serviços necessita de comunicar e enviar o pedido para o localizador de evidência. Com base nos requisitos técnicos OOTS (Once-only Technical System), além dos campos a enviar:

* O pedido é enviado por parâmetros de URL
* O localizador de evidência não requer autenticação do cidadão do pedido
* A informação enviada não é particularmente sensível, mas pode ser manipulada nos parâmetros do URL
* A gestão de chaves de encriptação com todos os portais com que o localizador irá comunicar pode ser uma tarefa complexa, e a sua necessidade será revista após a fase de testes do OOTS Projectathon
* É possível que haja alterações no caso de ser necessário um método mais seguro

Com base nesta informação, uma vez que não requer autenticação (e de forma a não expor tão facilmente os campos do pedido que podem ser adulterados no endereço URL da página), foi pensada a seguinte solução de ofuscação:

1. **Criação de uma mask key (chave de ofuscação) única associada ao portal de serviços:**

   * Esta chave é composta por uma string de 255 caracteres alfanuméricos
   * A chave é gerada pela equipa responsável pelo localizador de evidência durante o processo de integração, e é fornecida ao portal de serviços através de um canal seguro (a ser determinado)
   * A chave é secreta no sentido em que nunca deve ser exposta ao público
   * A chave é única para cada portal de serviços

2. **O portal de serviços codifica e mascara parte do conteúdo do pedido de evidência com o auxílio da chave de codificação:**

   * A codificação é realizada através de uma cifra de substituição XOR de forma a não ser demasiado simples como um único encoding em base64, nem demasiado complexa como o recurso a criptografia
   * O pedido de evidência é assumindo como partindo de um JSON string e depois convertido a base64, seguido da codificação por uma cifra de substituição com a chave de ofuscação
   * O resultado deverá ser um conjunto de caracteres alfanuméricos representados na constante MASK\_CHARS
   * É um método simples de encriptação simétrica e ofuscação, relativamente robusto a ataques de força bruta, cuja segurança está dependente do sigilo da chave

3. **O pedido codificado deverá ser depois encoded para URL e enviado para a página do localizador de evidência como parâmetro URL (ev-request) juntamente com o código identificador do portal de serviços (portal-id).**&#x20;

4. **O localizador de evidência vai obter a chave de codificação específica ao portal de serviços associado ao pedido, através do identificador do portal, e descodificar o pedido para obter o JSON string do pedido original.**

Para aplicar os passos 3 e 4, o portal de serviços deverá implementar o seguinte código. Para efeitos práticos e de apresentação, apresentamos o código na linguagem Java e os passos mais importantes em sequência:

5. **Obter a mask key** **fornecida ao portal de serviços no processo de integração e que estará associada ao portal de serviços que pretende integrar. Para este exemplo teremos a chave “42oszYRtoj3BgXu9” a título exemplificativo. Contudo, será fornecida mais tarde uma chave com 255 caracteres alfanuméricos no processo de integração.**
6. **Implementar os seguintes métodos auxiliares de codificação associados à chave de codificação:**

<pre class="language-java"><code class="lang-java">/** Caracteres que serão codificados **/
private static final String MASK_CHARS = 
 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZàáâãçéêíóôõú0123456789{}"/':-,”;
 
/** Conversão a Base64 **/
/** Importante converter o input a bytes para não haver problemas com nonASCII characters **/
<strong>public static String encodeToBase64(String input) {
</strong> byte[] encodedBytes = Base64.getEncoder().encode(input.getBytes());
 return new String(encodedBytes);
}

/** Codificação do pedido com base na Mask Key **/
public static String mask(String base64Input, String maskKey) {
 StringBuilder maskedText = new StringBuilder();
 String repeatedMaskKey = repeatMaskKey(base64Input, maskKey);
 
 for (int i = 0; i &#x3C; base64Input.length(); i++) {
  char currentChar = base64Input.charAt(i);
  char maskChar = repeatedMaskKey.charAt(i);
  int alphabetIndex = MASK_CHARS.indexOf(currentChar);
  
  if (alphabetIndex != -1) {
    int newIndex = (alphabetIndex + maskChar - 'a') % MASK_CHARS.length();
  
    if (newIndex &#x3C; 0) {
      newIndex += MASK_CHARS.length();
    }
    
    maskedText.append(MASK_CHARS.charAt(newIndex));
  } else {
    maskedText.append(currentChar);
  }
}
 
 return maskedText.toString();
}

/** Mask Key é repetida para acompanhar a totalidade do input **/
private static String repeatMaskKey(String input, String maskKey) {
  StringBuilder repeatedMaskKey = new StringBuilder();
  int textLength = input.length();

  for (int i = 0; i &#x3C; textLength; i++) {
    char maskChar = maskKey.charAt(i % maskKey.length());
    repeatedMaskKey.append(maskChar);
  }

  return repeatedMaskKey.toString();
}

/** Encoding para URL de modo a poder ser enviado como parâmetro **/
public static String encodeURLParameter(String text) {
  try {
    return URLEncoder.encode(text, StandardCharsets.UTF_8.toString());
  } catch (Exception e) {
    e.printStackTrace();
  }

  return "";
}
</code></pre>

A partir do JSON string do pedido, aplicar a seguinte sequência de codificações até obter o parâmetro a ser enviado. A demonstração abaixo inclui um exemplo de um pedido JSON num formato já desatualizado, contudo pode ser aplicado a qualquer tipo de input, desde que se trate de um JSON com a estrutura de dados correta e tenha um encoding UTF-8.

<pre class="language-java"><code class="lang-java"><strong>String jsonInput =
</strong>"{\"requirementId\":\"12345678\",\"redirectUrl\":\"https://eportugal.gov.pt\",\
"personData\":{\"levelOfAssurance\":\"high\",\"id\":\"PT/NL/123456789\",\"famil
yName\":\"Smith\",\"givenName\":\"Jack\",\"dateOfBirth\":\"1990-01-01\"}}";

String maskKey = "42oszYRtoj3BgXu9";
String base64JsonInput = encodeToBase64(jsonInput);
// Resultado:
eyJyZXF1aXJlbWVudElkIjoiMTIzNDU2NzgiLCJyZWRpcmVjdFVybCI6Imh0dHBzOi8vZXBvcnR1Z2F
sLmdvdi5wdCIsInBlcnNvbkRhdGEiOnsibGV2ZWxPZkFzc3VyYW5jZSI6ImhpZ2giLCJpZCI6IlBUL0
5MLzEyMzQ1Njc4OSIsImZhbWlseU5hbWUiOiJTbWl0aCIsImdpdmVuTmFtZSI6IkphY2siLCJkYXRlT
2ZCaXJ0aCI6IjE5OTAtMDEtMDEifX0=

String maskedInput = mask(base64JsonInput, maskKey);
// Resultado:
DVXQgPqco67YhN:YC1zC7b,B026"Tu'o"WuA{uuR/5:2id:NC29QAuthWvFvjyV3/FeNgP
mOqw:w5TZW{JrNCaQPrL65OeVPBK1NAcCArP2VUeMMA39cgOi8/t3"iU:2fbbBgKthWvF25TAM{ZXHg
uthWuZpRRh-
{WSQ}rBc1sAzUJ2W7J/zAO'Ls3lUhN'M/FX}AO'boL65OdxTCJ9MaeqM/16BObJLfhGA{uuD"6:YZTb
6zcXazuthWs2AUKUX}0SL}vpBt6g=

String urlEncodedInput = encodeURLParameter(maskedInput);
// Resultado:
DVXQgPqco67YhN%3AYC1zC7b%2CB026%22Tu%27o%22WuA%7BuuR%2F5%3A2id%3ANC29Q
AuthWvFvjyV3%2FFeNgPmOqw%3Aw5TZW%7BJrNCaQPrL65OeVPBK1NAcCArP2VUeMMA39cgOi8%2Ft3
%22iU%3A2fbbBgKthWvF25TAM%7BZXHguthWuZpRRh-
%7BWSQ%7DrBc1sAzUJ2W7J%2FzAO%27Ls3lUhN%27M%2FFX%7DAO%27boL65OdxTCJ9MaeqM%2F16BO
bJLfhGA%7BuuD%226%3AYZTb6zcXazuthWs2AUKUX%7D0SL%7DvpBt6g%3DUma vez obtida a JSON string codificada do pedido, enviar para a página do localizador de evidências como um parâmetro URL de acordo com a especificações abaixo.
</code></pre>

Uma vez obtida a JSON string codificada do pedido, enviar para a página do localizador de evidências como um parâmetro URL de acordo com a especificações abaixo.

**Parâmetros URL**

| Parâmetro  | Descrição                                                                                           | Observações                                                                                                          |
| ---------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| ev-request | O JSON string do pedido após codificação em base64, codificação com chave única, e codificação URL. | Conteúdo do pedido “EvidenceRequest” pode ser consultado abaixo.                                                     |
| portal-id  | Código de identificação do portal de serviços.                                                      | O código é fornecido pelo localizador de evidência para identificar o portal de serviços localmente.                 |
| request-id | Código de identificação gerado pelo portal de serviços.                                             | Utilizado para identificar todas as invocações de serviço relacionadas com o processo global de pedido de evidência. |

**Exemplo de URL de redireccionamento**

{% hint style="info" %}
**http\://\[domínio AutGov]/evidence-request?ev-request=**&#x44;TCy7uuR%2F63wgO3PAb9MCuthWL71jy%7D0BWCN%7BVyRZvp8jy6YC39Bz uQEr678ixYYgc8NBeGQr5J%7D5NdPAK5R%7BrqE0M%7BySd2p%7BuR%22vxM1MaxStcqgGua%7BOqD%22sbY5N6m%7DPC%22atLQrYTOeV2Ah1DgzGR%2F16BOt3i%7D%3AWK1alzWwZYie7ZAFWg7zd3WLYTO t3Wgc%2FDAwUF46%7D%22jO3LAJ1D7b%2CzWvF25TAM%7BXCy7ulzWvJXOaIK7IP%22 %7BSQ5ZI2%7DSq%7Bn%22Gqe%2FKtLQrYTOtUMgJTLzOig7v365J2s7ZX%7DAO'boL65I %2CUK7ZOAgU'd%2F5lj4NdP7GCy7caA%22%7DQVRrIK7ZOy7eCArPbk5b3TBK5G7b%2 CzWs2AUKUX%7D0SL%7DvpBQrYTlJQ'7ZOABeGDo67Y4U%7DhBJKA%2FalBoQ%3Aviy 6s%7BVfDByURrQb04NQYghfc%7BfmbWrUfOtUMBJ9PCOGSrPb%7D1yF0g%3AWg7u ucqvkB4T%3AQ%7BJ9b%2FeQAp5b%22UdFOgbbazOKI%2F66BXLZf%2FGyf%22vJBZJM TOt32gcTbgPyb%2F67j4NdPBVWg7xd3WLYTOyM'7ZOy7ulzWvVUhdwM%2FFOA-MPBZJMTOtUK7ZOAAeqM%2F16BOt3cBJfNgamO%2FrZ%225N7ZAJ5zBf%2Fz%2F5%3A w4TZmzbfM7yCIqPV8hNYZfh9QCy'Fo5%7DUjx'M1FOy7umkQrYT3JQ'7ZOAgfGLpN3X5y 3PBi0A%2FalB8wbUOx%7DP711HAOpLWMazO%2CQ'7ZOAAyUC%226%3A8ib%7DPBhz FAeqbp%226VU%2CUM%22-uA%7Bs%2CzWL79hU7m%3AhfCgKthWL6vSu'0%7B4b%22atLQrYTOeVZBi5VzPCg7v365J2s7ZX8AVubpH65I%2CUK7JTCAO'N95l2jvRPCJ9K% 7DKthWL7l1t2W1FOy7eqDp5J71NhTC1LDCeGL0r6BOt2M%7BXCy7uuPp%22%7D%22gN 3TA3zaDMKOquZ%7D5ObTgcqA%2FambqwbYIec%3&#x44;**\&portal-id=**&#x50;MC-TES&#x54;**\&request-id=**&#x62;f08b6db-3edd-47c3-b48b-b9ae5f3eae92
{% endhint %}

**EvidenceRequest**

| Campo                 | Descrição                                                                                                                   | Observações                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| requirement           | Identificador do requerimento                                                                                               |                                                                                                                     |
| procedure             | Identificador do procedimento                                                                                               |                                                                                                                     |
| redirectUrl           | Endereço para o redireccionamento de volta ao portal de serviços após o localizador enviar a evidência no final do processo | Endereço deve ser URL encoded. Endereço será também utilizado em caso de erro que não permita proceder no processo. |
| + person              | Dados da pessoa (natural person).                                                                                           |                                                                                                                     |
| ++ levelOfAssurance   | O nível mínimo de garantia eIDAS                                                                                            | “High”, “Medium”, ou “Low”. Case sensitive.                                                                         |
| ++ id                 | Identificador único eIDA                                                                                                    | Opcional                                                                                                            |
| ++ familyName         | Apelido da pessoa                                                                                                           |                                                                                                                     |
| ++ givenName          | Primeiro nome da pessoa                                                                                                     |                                                                                                                     |
| ++ dateOfBirth        | Data de nascimento da pessoa                                                                                                | Formato yyyy-MM-dd                                                                                                  |
| requesterId           | Identificador do portal                                                                                                     |                                                                                                                     |
| requesterType         | Identificador do tipo de portal                                                                                             |                                                                                                                     |
| + requesterNames      | Lista de nomes do portal em vários idiomas                                                                                  | Lista                                                                                                               |
| ++ lang               | Idioma                                                                                                                      | “EN”, “PT” …                                                                                                        |
| ++ name               | Nome do portal no idioma                                                                                                    |                                                                                                                     |
| fullAddress           | Morada da entidade solicitadora (portal)                                                                                    | Opcional                                                                                                            |
| locatorDesignator     | N.º da porta ou n.º do edifício da entidade solicitadora                                                                    | Opcional                                                                                                            |
| postCode              | Código postal da entidade solicitadora                                                                                      | Opcional                                                                                                            |
| postCityName          | Localidade da entidade solicitadora                                                                                         | Opcional                                                                                                            |
| adminUnitLevel1       | Código do nível mais alto da morada (quase sempre o código do país)                                                         | Opcional                                                                                                            |
| adminUnitLevel2       | Código do nível secundário da morada (costuma ser um código da cidade ou região)                                            | Opcional                                                                                                            |
| possibilityForPreview | Indica se é um pedido de evidência com possibilidade de pré-visualização da evidência                                       | Booleano                                                                                                            |

**Exemplo de JSON do EvidenceRequest**

```json
{
 "requirement": "https://sr.oots.tech.europa.eu/requirements/f8a6a284-34e9-42c7-9733-63b5c4f4aa42",
 "procedure": "T1",
 "person": {
  "levelOfAssurance": "High",
   "id": "PT/NL/123456789",
   "familyName": "Smith",
   "givenName": "Jack",
   "dateOfBirth": "1990-01-01"
 },
 "redirectUrl": "https%3A%2F%2Fportaldeprocedimentos.pt",
 "requesterType": "urn:cef.eu:names:identifier:EAS:9946",
 "requesterId": "9988b2b6-a23b-41d7-b373-7160e2190b38",
 "requesterNames": [
  {
   "lang": "EN",
   "name": "Procedure Portal"
  },
  {
   "lang": "PT",
   "name": "Portal de Procedimentos"
  }
 ],
 "fullAddress": "Rua de Cima, 58",
 "locatorDesignator": "58",
 "postCode": "4050-456",
 "postCityName": "Porto",
 "adminUnitLevel1": "PT",
 "adminUnitLevel2": "",
 "possibilityForPreview": true
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://guias.mosaico.gov.pt/adesao-ao-fornecedor-de-evidencias-localizador-de-evidencia/comunicacao-com-o-localizador-de-evidencia/redireccionamento-para-o-localizador-de-evidencia.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
