Nesta página vamos explicar como instalar um IdP Shibboleth 5.2.3 em Debian 13 integrado com Azure AD. Para esta instalação é utilizado um Playbook Ansible que automatiza a instalação e configuração do Apache2, Java 17.0.18, Tomcat 11.0.6, PostgreSQL e Shibboleth IdP 5.2.3.
A integração com Azure AD utiliza o Shibboleth IdP como um proxy SAML que assume simultaneamente o perfil de Identity Provider perante os serviços RCTSaai e o perfil de Service Provider perante a Azure AD:
- SAML PROXY - Shibboleth Perfil Service Provider: responsável por delegar a autenticação e recolha de atributos na Azure AD
- SAML PROXY - Shibboleth Perfil Identity Provider: responsável pelo mapeamento e filtragem de atributos para os serviços RCTSaai e eduGAIN
Este playbook permite fazer vários tipos de configuração. Permite:
- Instalar e configurar um IdP para ser possível fazer autenticação com Azure AD.
- Configurar um layout de acordo com a instituição.
- Atualizar um IdP existente para a versão 5.2.3.
1. Flow de autenticação do IdP com Azure AD
O utilizador acede ao serviço e é redirecionado para o IdP para se autenticar. O IdP, por estar a funcionar como SAML Proxy, delega a autenticação na Azure AD e por esta razão redireciona o utilizador para o tenant Azure AD.
Após uma autenticação com sucesso, a Azure AD recolhe os dados/atributos do utilizador e redireciona novamente o utilizador para o IdP, enviando-lhe os respetivos atributos.
O IdP é responsável por mapear e filtrar os atributos recebidos antes de os enviar para os serviços. Por fim, o utilizador consente o envio dos atributos ao serviço e tem acesso ao mesmo. A salientar que este utilizador terá uma sessão ativa na Azure AD e outra no Shibboleth IdP.

2. Configuração do Tenant Azure AD
Nesta secção vamos demonstrar como configurar o tenant Azure AD. Esta configuração deve ser realizada antes da instalação do playbook Ansible.
2.1 Criar Aplicação
É necessário criar uma Azure AD Enterprise Application do tipo Non-Gallery Application.
Escolha Enterprise Applications
- Carregue em "New Application"
- Escolha a opção "Non Gallery Application" e adicione o nome da aplicação (ex.: SAML IDP)
- Após criar a aplicação siga para a opção "Set up single sign on"
- Selecione a opção SAML
Na opção SAML deve adicionar a seguinte informação do IdP:
- Adicione o EntityID do IdP:
https://idp.dominio-da-instituicao.pt/idp/shibboleth - Adicione o Assertion Consumer Service (ACS) do IdP:
https://idp.dominio-da-instituicao.pt/idp/profile/Authn/SAML2/POST/SSO
O IdP ainda não se encontra instalado, no entanto deve colocar os links de acordo com o URL que o seu IdP irá obter.
Em https://idp.dominio-da-instituicao.pt substitua de acordo com o domínio da sua instituição.
2.2 Metadados do Azure AD
Transfira os metadados do tenant na Secção 3 da informação de Relying Party do Azure AD, carregando no link de Download referente à opção Federation Metadata XML. Guarde o ficheiro transferido com o nome AzureAD-idp.xml.

O ficheiro AzureAD-idp.xml necessita de duas alterações no elemento IDPSSODescriptor:
- Adicione a opção
xmlns:shibmd="urn:mace:shibboleth:metadata:1.0":
<IDPSSODescriptor
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:shibmd="urn:mace:shibboleth:metadata:1.0">
- Dentro do elemento
IDPSSODescriptoradicione o seguinte bloco:
<Extensions>
<shibmd:Scope regexp="false">dominio_da_instituicao.pt</shibmd:Scope>
</Extensions>
Altere o "dominio_da_instituicao.pt" de acordo com o domínio da sua instituição.
Para o exemplo FCCN seria substituído por fccn.pt.
O elemento shibmd:Scope permite realizar o filtro do azureName tendo em conta o domínio inserido — para o exemplo FCCN apenas seriam aceites os utilizadores cujo azureName contenha fccn.pt (ex.: authmonit@fccn.pt).
Após editar o ficheiro, copie-o para a pasta files/ORG/idp-azure-ad/ antes de executar o playbook. O playbook irá automaticamente colocá-lo na pasta de metadados do IdP e adicioná-lo como MetadataProvider.
2.3 Atributos Azure AD
Ainda no modo de edição da Relying Party é necessário configurar o Azure AD para libertar os atributos para o Shibboleth IdP.
Os utilizadores necessitam de ter os seguintes atributos preenchidos:
- name
- givenName
- surname
- emailaddress
- Unique User Identifier
- displayName

O atributo user.principalname corresponde ao identificador único e permanente do utilizador na instituição para todos os serviços. Este será utilizado como canonicalNameToUseForJoin para identificar o utilizador no IdP.
3. Pré-requisitos
O primeiro passo a efectuar é instalar o pacote ansible e unzip.
shell> apt install ansible unzip
Crie a pasta Shibboleth_IDP_5.2.3, entre na nova diretoria e descomprima o código para dentro da mesma:
shell> mv shibboleth-idp-5-2-3-debian-ORG.zip Shibboleth_IDP_5.2.3
shell> cd Shibboleth_IDP_5.2.3
shell> unzip shibboleth-idp-5-2-3-debian-ORG.zip
4. Configuração do playbook
Edite o ficheiro de definições gerais sobre a instituição e da instalação em curso no seguinte ficheiro:
shell> vi group_vars/all.yml
Descrição dos parâmetros a definir
A instalação do Shibboleth IdP depende das parametrizações efectuadas no ficheiro all.yml. Em baixo encontram-se descritas as parametrizações necessárias de preencher relativas à sua instituição:
4.1 Configurações Gerais do Apache
fqdn: hostname do idp a ser instalado (ex.: idp.fccn.pt)server_admin: contacto de admin do servidor (ex.: idp-admin@fccn.pt)
4.2 Configuração SSL - Certificados
| Tradicional | ACME |
|---|---|
| configure_SSL_certificates: "Tradicional" | configure_SSL_certificates: "ACME" |
4.2.1 Configuração SSL Tradicional
configure_SSL_certificates: "Tradicional"path_ssl_cert_apache: Localização dos certificados/chaves públicas usadas pelo apache (ex.: /etc/ssl/certs)path_ssl_cert_apache_private: Localização dos certificados/chaves privadas usadas pelo apache (ex.: /etc/ssl/private)
Copiar ficheiros de certificados SSL do IdP para files/ORG/ssl-certs/
ssl_cert_key_file_name: Nome do ficheiro que contém o certificado privado usado pelo apache (ex.: idp_fccn_pt.key)ssl_cert_file_name: Nome do ficheiro que contém o certificado público usado pelo apache (ex.: idp_fccn_pt_cert.cer)ssl_cert_chain_file_name: Nome do ficheiro que contém os certificados da cadeia de confiança usada pelo apache (ex.: idp_fccn_pt_interm.cer)
4.2.2 Configuração SSL ACME
O cliente de ACME (certbot) necessita de credenciais de uma conta ACME (mac_id e mac_key), pelo que antes da execução Ansible, o Administrador da Instituição responsável pelos certificados SSL deve criar/configurar uma conta ACME no portal da HARICA associada aos domínios desejados.
configure_SSL_certificates: "ACME"path_ssl_cert_apache: /etc/letsencrypt/live/{{ fqdn }} Não alterarpath_ssl_cert_apache_private: /etc/letsencrypt/live/{{ fqdn }} Não alterarssl_cert_key_file_name: Nome do ficheiro que contém o certificado privado usado pelo apache (ex.: privkey.pem)ssl_cert_file_name: Nome do ficheiro que contém o certificado público e da cadeia de confiança usada pelo apache (ex.: fullchain.pem)option_multi_domain: "single-domain" Não alteraroption_encryption_algorithm: ecdsa Não alteraroption_acme_account_name: IDP Não alteraroption_common_names_list: "{{ fqdn }}" Não alterarcontact_email: Contacto de email do responsável por esta configuraçãoacme_accounts:name: IDP Não alterarca: acme-v02.harica.gr Não alterarserver: URL do diretório do servidor da HARICA associado à conta ACME (ex.: https://acme-v02.harica.gr/acme//directory) mac_id: Adicionar a EAB Key ID da conta ACME previamente criadamac_key: Adicionar o EAB HMAC Key da conta ACME previamente criada
4.3. Configurações Fail2Ban
destemail: endereço de e-mail para onde serão enviadas as notificações do Fail2Ban (ex.: admin@org.pt)sender: endereço de e-mail que aparecerá como remetente nas notificações do Fail2Ban (ex.: admin@org.pt)
4.4. Configurações Tomcat
tomcat_major_version: 11 — versão do tomcat a utilizar. Não alterartomcat_version: 11.0.6 — versão do tomcat a utilizar. Não alterartomcat_xms: tamanho de heap size inicial em memória no arranque do Tomcat (ex.: 1024M)tomcat_xmx: tamanho de heap size máximo em memória do Tomcat (ex.: 4096M)
4.5. Configurações Shibboleth
idp_version: versão do Fornecedor de Identidade. Não alterarsource_directory: diretoria onde são colocados os ficheiros de instalação do Shibboleth IdP. Por defeito:/usr/local/dist/shibboleth-identity-provider-5.2.3. Não alterarinstallation_directory: diretoria de instalação do Shibboleth IdP. Por defeito:/opt/shibboleth-idp. Não alterarupdate_idp: indica se pretende atualizar ou instalar o IdP de raiz. Para atualizar coloquetrue, para instalar de raiz coloquefalseip_range_access_control: Intervalo de IPs que podem aceder a endpoints sensíveis (ex.: https://HOSTNAME/idp/status). A rede deve estar obrigatoriamente entre plicas (ex.: "'133.16.11.0/24', '133.16.10.0/24'")attribute_scope: Domínio da organização utilizado nos metadados e atributos (schacHomeOrganization, eduPersonScopedAffiliation) (ex.: fccn.pt)organization_name: nome da instituição (ex.: Fundação para a Computação Científica Nacional)ou_organization_name: nome da unidade orgânica da instituição, caso se aplique (ex.: FCCN, Serviços Digitais FCT)user_test: username da conta de monitorização fornecida à FCCN. O nome de utilizador padrão émonitidp
Configuração de Armazenamento de sessões do IdP
idp_session_storage: Define como deve ser armazenada a informação de sessão do utilizador. "Server-Side" armazena as sessões no servidor na BD PostgreSQL ou "Client-Side" armazena as sessões no cliente (Recomendado)
Configuração de Armazenamento de Termos e Condições e Consentimento
idp_consent_storage: Define como deve ser armazenada a informação de consentimento. "Server-Side" armazena os pedidos de consentimento e termos e condições no servidor na BD PostgreSQL ou "Client-Side" armazena os pedidos de consentimento e termos e condições no cliente.
Configuração de Identificadores Antigos (Transient + eduPersonTargetId)
idp_old_persistentId_salt: se for atualizar o IdP a partir de uma versão antiga, coloque o valor antigo do salt. Caso contrário pode manter este campo vazio.idp_old_persistentId_sourceAttribute: Identifique o atributo que seja único para cada utilizador, que permaneça inalterado durante todo o ciclo de vida na instituição e que não seja reutilizado após a sua saída.idp_old_persistenteId_generator: Define como deve ser armazenado o persistentId. "Stored" armazena o persistentId na base de dados PostgreSQL (recomendado) ou "Computed" calcula o persistentId dinamicamente sem armazenamento em BD.
Configuração de Identificadores Novos (samlPairwiseID + samlSubjectID)
Nota: É de extrema importância que o persistentId_sourceAttribute seja preenchido com um atributo único para cada utilizador, que permaneça inalterado durante todo o ciclo de vida na instituição e que não seja reutilizado após a sua saída.
idp_persistentId_salt: se for atualizar o IdP a partir de uma versão antiga e já tenha definido estes novos identificadores, coloque o valor antigo do salt. Caso contrário pode manter este campo vazio.idp_persistentId_sourceAttribute: Identifique o atributo que seja único para cada utilizador, que permaneça inalterado durante todo o ciclo de vida na instituição e que não seja reutilizado após a sua saída.idp_persistenteId_generator: Define como deve ser armazenado o persistentId. "Stored" armazena o persistentId na base de dados PostgreSQL (recomendado) ou "Computed" calcula o persistentId dinamicamente sem armazenamento em BD.
Configuração da BD PostgreSQL
postgresql_version: versão do PostgreSQL a instalar. Não alterarpostgresql_host: endereço do servidor PostgreSQL. Por defeito:localhost. Não alterarbackup_bd_shib: Indica se deseja utilizar o backup do IdP de produção em caso de atualização (update_idp: true). Definatruepara utilizar o backup oufalsepara não utilizar.
Comando a utilizar para realizar o PostgreSQL dump:
sudo pg_dump -U shibboleth -F c -f shibboleth
Copiar ficheiro para a seguinte localização files/ORG/idp-postgres-backup/
bd_backup_file_name: nome do ficheiro de backup da base de dados PostgreSQL (ex.: bd.sql)postgresql_database: shibboleth Não alterarpostgresql_username: shibboleth Não alterarpostgresql_password: password de acesso à base de dados PostgreSQL — adicionar entre pelicaspostgresql_backup_dest: caminho para a pasta onde ficarão alojados os backups da base de dados./var/lib/postgresql/backupsNão alterar
Configuração de Metadados do IdP
idp_entityID: Identificador único do IdP. Em caso de atualização (update_idp: true), mantenha o valor igual ao entityID do IdP atualmente em produção (ex.: https://idp.fccn.pt/idp/shibboleth)idp_metadata_name: idp-metadata Não alterar
Nota: Em caso de atualização (update_idp: true) deve copiar os ficheiros dos certificados na pasta files/ORG/idp-metadata-certs/
idp_sign_cert_name: nome do ficheiro que contém o certificado utilizado para assinar asserções do IdP (ex.: idp-signing.crt)idp_sign_key_name: nome do ficheiro que contém a chave privada utilizada para assinar asserções do IdP (ex.: idp-signing.key)idp_encryption_cert_name: nome do ficheiro que contém o certificado utilizado para cifrar asserções do IdP (ex.: idp-encryption.crt)idp_encryption_key_name: nome do ficheiro que contém a chave privada utilizada para cifrar asserções do IdP (ex.: idp-encryption.key)idp_backchannel_cert_name: nome do ficheiro que contém o certificado utilizado para comunicação em backchannel com o IdP (ex.: idp-backchannel.crt)idp_backchannel_key_name: nome do ficheiro que contém a chave privada utilizada para comunicação em backchannel (ex.: idp-backchannel.p12)
Configuração de Ligação ao Azure AD
type_of_idp: definir comoazurepara integração com Azure ADazure_url: URL do tenant Azure AD da organização (ex.: https://sts.windows.net//)
O playbook configura automaticamente o fluxo de autenticação SAML Proxy com os seguintes parâmetros:
idp.authn.flows = SAML— ativa o fluxo de autenticação via SAML Proxyidp.authn.SAML.proxyEntityID— definido automaticamente com o valor deazure_urlidp.authn.SAML.discoveryRequired = true— ativa a descoberta automática do IdP Azure
O atributo canonicalNameToUseForJoin é utilizado internamente para identificar o utilizador com base no user.principalname recebido da Azure AD.
Configuração do Sealer (sincronização de chaves)
O Sealer é responsável por cifrar tokens de sessão do IdP. O script updateSealerKeys.sh é executado diariamente via cron e, após gerar novas chaves com o seckeygen.sh, sincroniza os ficheiros resultantes (storefile e versionfile) para os restantes IdPs via SCP.
-
Um único IdP: não é necessário configurar estas variáveis. O script gera as chaves localmente e não executa qualquer SCP.
-
Múltiplos IdPs: é obrigatório configurar ambas as variáveis para garantir que as chaves são sincronizadas entre todos os IdPs.
-
idp_sealer_cron_host: hostname do IdP onde a cron será ativada pelo playbook. Apenas um IdP deve executar o script — o que irá gerar as chaves e sincronizá-las para os restantes via SCP (ex.: idp1.fccn.pt) -
idp_sealer_sync_hosts: lista de hostnames de todos os IdPs separados por espaço. Deve incluir também o hostname do IdP onde o script corre, uma vez que o script o deteta automaticamente e ignora-o, ativando o SCP apenas para os restantes (ex.:idp1.fccn.pt idp2.fccn.pt) -
idp_sealer_sync_user: utilizador com permissões SSH/SCP nos IdPs de destino, utilizado para transferir os ficheiros de chaves. Por defeito:root
Pré-requisitos para ambientes multi-IdP:
- Gerar o par de chaves SSH no IdP que executa o script (se não existir):
ssh-keygen -t rsa -b 4096 -f /opt/tomcat/.ssh/id_rsa -N "" - Copiar a chave pública para cada um dos IdPs de destino:
ssh-copy-id -i /opt/tomcat/.ssh/id_rsa.pub <idp_sealer_sync_user>@<hostname_idp_destino>Ou manualmente, adicionar o conteúdo de
/opt/tomcat/.ssh/id_rsa.pubao ficheiro/home/tomcat/.ssh/authorized_keysem cada um dos IdPs de destino.
Configuração de Metadata Providers
-
idp_metadata_providers: Nesta secção podem ser adicionados vários "Metadata Providers". No ficheiro all.yml já se encontram os providers necessários (RCTSaai, RCTSaai Engine PRD, RCTSaai Engine QUA e Interfederação). O playbook adiciona automaticamente o MetadataProvider do Azure AD a partir do ficheiro AzureAD-idp.xml. Caso pretenda adicionar um novo provider é necessário preencher a seguinte secção:id: Identificador do Provider (ex.: "RCTSaaiMD")
file: Nome do ficheiro onde deve ser armazenado (ex.: "metadata.rctsaai.xml")
url: URL onde se pode realizar o download (ex.: "https://registry.rctsaai.pt/rr/signedmetadata/federation/rctsaai/metadata.xml")
maxValidInterval: "P7D" Não alterar
disregardTLSCertificate: "false" Não alterar
pubKey: adicionar o certificado de verificação de assinatura. Para obter a chave pública a partir de um certificado PEM executar:openssl x509 -pubkey -noout -in <certificado>.pem
Configuração de Layout
Se for necessário atualizar o logótipo ou a imagem de fundo do IdP, siga as seguintes instruções:
- Logótipo: adicione o ficheiro na pasta /files/ORG/idp-layout/NomeDaInstituicao/images/ e indique o seu nome na variável
idp_logo_img_name - Background: adicione o ficheiro na pasta /files/ORG/idp-layout/NomeDaInstituicao/images/ e indique o seu nome na variável
idp_bg_img_name
Altere o nome da pasta NomeDaInstituicao para um nome apropriado no contexto da instituição e coloque-o na variável org_layout.
org_layout: nome da pasta do layout da organização (ex.: FCCN)organization_domain: domínio da organização (ex.: fccn.pt)idp_logo_img_name: nome da imagem com o logotipo da instituiçãoidp_logo_url: URL para o qual o utilizador será redirecionado ao clicar no logotipoidp_bg_img_name: nome da imagem de fundo da instituiçãolink_suporte: URL para uma página de suporte da organizaçãolink_rctsaai: URL para a página com informação sobre a RCTSaailink_seguranca: URL para uma página com informação sobre segurança relevante para o utilizadorlink_ajuda: URL para uma página com informação que possa ajudar o utilizador (ex.: FAQ)link_esqueceu_palavra_chave: URL para uma página onde é possível redefinir a palavra-chave
5. Instalação e Configuração Base do IdP
Após o preenchimento do ficheiro de configurações (all.yml), o IdP pode ser instalado executando o playbook.
Para realizar a instalação base do Shibboleth IdP 5.2.3 utilize o seguinte comando:
shell> ansible-playbook -vv -i "localhost," --connection=local main.yml --tags=base