Keycloak retornando {"error":"Bearer token format error"} ao obter clientes pela interface REST

Keycloak retornando {"error":"Bearer token format error"} ao obter clientes pela interface REST

Procurando uma maneira de configurar um ambiente keycloak, crie um novo domínio e preencha com clientes/usuários para obter um endpoint OAuth mínimo usando a interface REST/CURL.

Keycloak retornando {"error":"Erro no formato do token de portador"}

Estou no Windows 10 Pro + Docker

Não estou nem conseguindo obter a lista de clientes do Reino Mestre.

Estou fazendo conforme documentado em:

"keycloak-documentation/server_development/topics/admin-rest-api.adoc"
.
E também em:

"Obter clientes pertencentes ao domínio (GET /{realm}/clients)"
.
"Autorização: portador eyJhbGciOiJSUz..."
.
"Como as funções do Keycloak são gerenciadas?" .

Como forma de alcançar:

criando um domínio via REST /auth/admin/realms
.
O roteiro em si:

    mkdir test
    cd test
    npm install -g underscore-cli
    docker run --name keyclk01 -e KEYCLOAK_USER=admuser -e KEYCLOAK_PASSWORD=admpass -p 8444:8443 -p 8081:8080 -p 9991:9990 jboss/keycloak
    docker restart keyclk01
    docker inspect --format "{{.NetworkSettings.IPAddress}}" keyclk01
    curl --proxy 127.0.0.1:8888 -k --url https://127.0.0.1:8444/auth/realms/master/protocol/openid-connect/token -d "username=admuser&password=admpass&client_id=admin-cli&grant_type=password" > 01Raw.json
    type 01Raw.json | underscore pretty
    type 01Raw.json | underscore select ".access_token" | underscore reduce 0 > 02RawToken
    echo|set /p="Authorization: Bearer " > 03HeaderTpl
    type 03HeaderTpl 02RawToken > 04Header
    findstr "." 04Header > 05HeaderFix
    curl --proxy 127.0.0.1:8888 -k --url "https://127.0.0.1:8444/auth/admin/realms/master/clients" -H @05HeaderFix
    curl --proxy 127.0.0.1:8888 -k --url "https://127.0.0.1:8444/auth/admin/realms/master" -H @05HeaderFix
    curl --proxy 127.0.0.1:8888 -k --url "http://127.0.0.1:8444/auth/admin/realms/master/clients" -H @05HeaderFix -o responseFile01.txt
    curl --proxy 127.0.0.1:8888 -k --url "http://127.0.0.1:8444/auth/admin/realms/master" -H @05HeaderFix -o responseFile02.txt
    curl -k --url "http://127.0.0.1:8444/auth/admin/realms/master/clients" -H @05HeaderFix -o responseFile01.txt
    powerShell: Format-Hex responseFile01.txt ==>   0x15 0x03 0x03 0x00 0x02 0x02 0x50
    curl -k --url "http://127.0.0.1:8444/auth/admin/realms/master" -H @05HeaderFix -o responseFile02.txt
    powerShell: Format-Hex responseFile02.txt ==>   0x15 0x03 0x03 0x00 0x02 0x02 0x50

As mensagens http recebidas com o Fiddler:
(O "Este servidor com bugs não retornou cabeçalhos" parece ser do proxy Fiddler)

------------------------------------------------------------------------------------------------------------
POST https://127.0.0.1:8444/auth/realms/master/protocol/openid-connect/token HTTP/1.1
Host: 127.0.0.1:8444
User-Agent: curl/7.55.1
Accept: */*
Content-Length: 73
Content-Type: application/x-www-form-urlencoded

username=admuser&password=admpass&client_id=admin-cli&grant_type=password
------------------------------------------------------------------------------------------------------------
HTTP/1.1 200 OK
Connection: keep-alive
Cache-Control: no-store
Set-Cookie: KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/master/; HttpOnly
Pragma: no-cache
Content-Type: application/json
Content-Length: 1783
Date: Wed, 06 Nov 2019 17:28:52 GMT

{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0RF9JNHY2dHJtWnBMQTg4aFU2V1ZXb0dCcVdwSm0xRW51ajVEWjVuQWE4In0.eyJqdGkiOiI0MTQ4MzgyNi1kOGMyLTQ5ZmEtOWQ1My0xNjY3NjIwM2IzMmIiLCJleHAiOjE1NzMwNjEzOTIsIm5iZiI6MCwiaWF0IjoxNTczMDYxMzMyLCJpc3MiOiJodHRwczovLzEyNy4wLjAuMTo4NDQ0L2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjA2ODRjZDJmLWU4YWItNDEzNy1hNDMzLTAyNWE1OTcyOTdjOCIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjYwNWVkZTE1LWU4Y2EtNDQ1OS1iYjQ0LTliMzQ5NzA3NzUwZSIsImFjciI6IjEiLCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6ImFkbXVzZXIifQ.I-snNpKcCFBmhbF5pQox_FZx9SVVhxZppYz3xe0mVgBRIysc8q80T1hpwU15D_mhSQ4UxA875dwYtmq6UHVEG5qbPpCmAqV3YZXfCm2MtSyXiQflibIf6JemoON3QL645N--Y3nFI3mTu5CN9IUyvlXKR4f-AwmxJW1OhyjoyGiVLhJ3MMSKdp2x7MCPBQyuSKdIQLEyeCpWuGj6bviG2jm44xlsigKjGkW7X13bs-CqNwODPdOISX_4cxNnQhClmI6mpoXFW9fhYwLpOdx8vG3gi_5P-IuX6oCNUTyFnkpfOTmbacfG7bqUUwcPeUcjHkQdm9QuJWYmqffWTiJN-w","expires_in":60,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzOGFmYTg4OC01ZWQ4LTRhZTQtYTU3My00OGNmODRlNDA4YTEifQ.eyJqdGkiOiJlZTE4NGNhYy0xZmY0LTRiNTMtYTBmNy1mYWQ5N2FjZDgwZjIiLCJleHAiOjE1NzMwNjMxMzIsIm5iZiI6MCwiaWF0IjoxNTczMDYxMzMyLCJpc3MiOiJodHRwczovLzEyNy4wLjAuMTo4NDQ0L2F1dGgvcmVhbG1zL21hc3RlciIsImF1ZCI6Imh0dHBzOi8vMTI3LjAuMC4xOjg0NDQvYXV0aC9yZWFsbXMvbWFzdGVyIiwic3ViIjoiMDY4NGNkMmYtZThhYi00MTM3LWE0MzMtMDI1YTU5NzI5N2M4IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImFkbWluLWNsaSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjYwNWVkZTE1LWU4Y2EtNDQ1OS1iYjQ0LTliMzQ5NzA3NzUwZSIsInNjb3BlIjoicHJvZmlsZSBlbWFpbCJ9.j9-VpOQ8qEmz8KfctOz6tKdlUmOuuUFgeR6unbhdjOc","token_type":"bearer","not-before-policy":0,"session_state":"605ede15-e8ca-4459-bb44-9b349707750e","scope":"profile email"}
------------------------------------------------------------------------------------------------------------
============================================================================================================
------------------------------------------------------------------------------------------------------------
GET https://127.0.0.1:8444/auth/admin/realms/master/clients HTTP/1.1
Host: 127.0.0.1:8444
User-Agent: curl/7.55.1
Accept: */*
Authorization: Bearer "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0RF9JNHY2dHJtWnBMQTg4aFU2V1ZXb0dCcVdwSm0xRW51ajVEWjVuQWE4In0.eyJqdGkiOiI0MTQ4MzgyNi1kOGMyLTQ5ZmEtOWQ1My0xNjY3NjIwM2IzMmIiLCJleHAiOjE1NzMwNjEzOTIsIm5iZiI6MCwiaWF0IjoxNTczMDYxMzMyLCJpc3MiOiJodHRwczovLzEyNy4wLjAuMTo4NDQ0L2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjA2ODRjZDJmLWU4YWItNDEzNy1hNDMzLTAyNWE1OTcyOTdjOCIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjYwNWVkZTE1LWU4Y2EtNDQ1OS1iYjQ0LTliMzQ5NzA3NzUwZSIsImFjciI6IjEiLCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6ImFkbXVzZXIifQ.I-snNpKcCFBmhbF5pQox_FZx9SVVhxZppYz3xe0mVgBRIysc8q80T1hpwU15D_mhSQ4UxA875dwYtmq6UHVEG5qbPpCmAqV3YZXfCm2MtSyXiQflibIf6JemoON3QL645N--Y3nFI3mTu5CN9IUyvlXKR4f-AwmxJW1OhyjoyGiVLhJ3MMSKdp2x7MCPBQyuSKdIQLEyeCpWuGj6bviG2jm44xlsigKjGkW7X13bs-CqNwODPdOISX_4cxNnQhClmI6mpoXFW9fhYwLpOdx8vG3gi_5P-IuX6oCNUTyFnkpfOTmbacfG7bqUUwcPeUcjHkQdm9QuJWYmqffWTiJN-w"


------------------------------------------------------------------------------------------------------------
HTTP/1.1 401 Unauthorized
Connection: keep-alive
Content-Type: application/json
Content-Length: 37
Date: Wed, 06 Nov 2019 17:28:53 GMT

{"error":"Bearer token format error"}
------------------------------------------------------------------------------------------------------------
============================================================================================================
------------------------------------------------------------------------------------------------------------
GET https://127.0.0.1:8444/auth/admin/realms/master HTTP/1.1
Host: 127.0.0.1:8444
User-Agent: curl/7.55.1
Accept: */*
Authorization: Bearer "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0RF9JNHY2dHJtWnBMQTg4aFU2V1ZXb0dCcVdwSm0xRW51ajVEWjVuQWE4In0.eyJqdGkiOiI0MTQ4MzgyNi1kOGMyLTQ5ZmEtOWQ1My0xNjY3NjIwM2IzMmIiLCJleHAiOjE1NzMwNjEzOTIsIm5iZiI6MCwiaWF0IjoxNTczMDYxMzMyLCJpc3MiOiJodHRwczovLzEyNy4wLjAuMTo4NDQ0L2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjA2ODRjZDJmLWU4YWItNDEzNy1hNDMzLTAyNWE1OTcyOTdjOCIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjYwNWVkZTE1LWU4Y2EtNDQ1OS1iYjQ0LTliMzQ5NzA3NzUwZSIsImFjciI6IjEiLCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6ImFkbXVzZXIifQ.I-snNpKcCFBmhbF5pQox_FZx9SVVhxZppYz3xe0mVgBRIysc8q80T1hpwU15D_mhSQ4UxA875dwYtmq6UHVEG5qbPpCmAqV3YZXfCm2MtSyXiQflibIf6JemoON3QL645N--Y3nFI3mTu5CN9IUyvlXKR4f-AwmxJW1OhyjoyGiVLhJ3MMSKdp2x7MCPBQyuSKdIQLEyeCpWuGj6bviG2jm44xlsigKjGkW7X13bs-CqNwODPdOISX_4cxNnQhClmI6mpoXFW9fhYwLpOdx8vG3gi_5P-IuX6oCNUTyFnkpfOTmbacfG7bqUUwcPeUcjHkQdm9QuJWYmqffWTiJN-w"


------------------------------------------------------------------------------------------------------------
HTTP/1.1 401 Unauthorized
Connection: keep-alive
Content-Type: application/json
Content-Length: 37
Date: Wed, 06 Nov 2019 17:28:53 GMT

{"error":"Bearer token format error"}
------------------------------------------------------------------------------------------------------------
============================================================================================================
------------------------------------------------------------------------------------------------------------
GET http://127.0.0.1:8444/auth/admin/realms/master/clients HTTP/1.1
Host: 127.0.0.1:8444
User-Agent: curl/7.55.1
Accept: */*
Connection: Keep-Alive
Authorization: Bearer "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0RF9JNHY2dHJtWnBMQTg4aFU2V1ZXb0dCcVdwSm0xRW51ajVEWjVuQWE4In0.eyJqdGkiOiI0MTQ4MzgyNi1kOGMyLTQ5ZmEtOWQ1My0xNjY3NjIwM2IzMmIiLCJleHAiOjE1NzMwNjEzOTIsIm5iZiI6MCwiaWF0IjoxNTczMDYxMzMyLCJpc3MiOiJodHRwczovLzEyNy4wLjAuMTo4NDQ0L2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjA2ODRjZDJmLWU4YWItNDEzNy1hNDMzLTAyNWE1OTcyOTdjOCIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjYwNWVkZTE1LWU4Y2EtNDQ1OS1iYjQ0LTliMzQ5NzA3NzUwZSIsImFjciI6IjEiLCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6ImFkbXVzZXIifQ.I-snNpKcCFBmhbF5pQox_FZx9SVVhxZppYz3xe0mVgBRIysc8q80T1hpwU15D_mhSQ4UxA875dwYtmq6UHVEG5qbPpCmAqV3YZXfCm2MtSyXiQflibIf6JemoON3QL645N--Y3nFI3mTu5CN9IUyvlXKR4f-AwmxJW1OhyjoyGiVLhJ3MMSKdp2x7MCPBQyuSKdIQLEyeCpWuGj6bviG2jm44xlsigKjGkW7X13bs-CqNwODPdOISX_4cxNnQhClmI6mpoXFW9fhYwLpOdx8vG3gi_5P-IuX6oCNUTyFnkpfOTmbacfG7bqUUwcPeUcjHkQdm9QuJWYmqffWTiJN-w"


------------------------------------------------------------------------------------------------------------
HTTP/1.0 200 This buggy server did not return headers

 P
------------------------------------------------------------------------------------------------------------
============================================================================================================
------------------------------------------------------------------------------------------------------------
GET http://127.0.0.1:8444/auth/admin/realms/master HTTP/1.1
Host: 127.0.0.1:8444
User-Agent: curl/7.55.1
Accept: */*
Connection: Keep-Alive
Authorization: Bearer "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0RF9JNHY2dHJtWnBMQTg4aFU2V1ZXb0dCcVdwSm0xRW51ajVEWjVuQWE4In0.eyJqdGkiOiI0MTQ4MzgyNi1kOGMyLTQ5ZmEtOWQ1My0xNjY3NjIwM2IzMmIiLCJleHAiOjE1NzMwNjEzOTIsIm5iZiI6MCwiaWF0IjoxNTczMDYxMzMyLCJpc3MiOiJodHRwczovLzEyNy4wLjAuMTo4NDQ0L2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjA2ODRjZDJmLWU4YWItNDEzNy1hNDMzLTAyNWE1OTcyOTdjOCIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjYwNWVkZTE1LWU4Y2EtNDQ1OS1iYjQ0LTliMzQ5NzA3NzUwZSIsImFjciI6IjEiLCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6ImFkbXVzZXIifQ.I-snNpKcCFBmhbF5pQox_FZx9SVVhxZppYz3xe0mVgBRIysc8q80T1hpwU15D_mhSQ4UxA875dwYtmq6UHVEG5qbPpCmAqV3YZXfCm2MtSyXiQflibIf6JemoON3QL645N--Y3nFI3mTu5CN9IUyvlXKR4f-AwmxJW1OhyjoyGiVLhJ3MMSKdp2x7MCPBQyuSKdIQLEyeCpWuGj6bviG2jm44xlsigKjGkW7X13bs-CqNwODPdOISX_4cxNnQhClmI6mpoXFW9fhYwLpOdx8vG3gi_5P-IuX6oCNUTyFnkpfOTmbacfG7bqUUwcPeUcjHkQdm9QuJWYmqffWTiJN-w"


------------------------------------------------------------------------------------------------------------
HTTP/1.0 200 This buggy server did not return headers

 P
------------------------------------------------------------------------------------------------------------
============================================================================================================

Responder1

Eu faço exatamente o que você descreve, mas uso Python para analisar o JSON. Aqui está o que eu faço:

ACCESS_TOKEN=$(curl -s -k -d 'client_id=admin-cli' \
                          -d 'username=admin' \
                          -d "password=$KEYCLOAK_PW" \
                          -d 'grant_type=password' \
                         "https://${KEYCLOAK_SERVER}/auth/realms/master/protocol/openid-connect/token" | python -c '
import json,sys;keycloak_data=json.load(sys.stdin);print keycloak_data["access_token"]')

Crie o reino:

cat <<! | curl -k -s \
        -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: bearer $ACCESS_TOKEN" \
        --data-binary @- "https://${KEYCLOAK_SERVER}/auth/admin/realms"
{"enabled":true,"id":"myrealm","realm":"myrealm"}
!

Adicione no cliente

cat <<! | curl -s -k \
        -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: bearer $ACCESS_TOKEN" \
        --data-binary @- "https://${KEYCLOAK_SERVER}/auth/admin/realms/myrealm/clients"
{
                "clientId": "$INSTANCE_NAME",
                "clientAuthenticatorType": "client-secret",
                "protocol": "openid-connect",
                "fullScopeAllowed": false,
                "authorizationServicesEnabled": true,
                "serviceAccountsEnabled": true,
                "redirectUris" : [ "https://$INSTANCE/*" ],
                "publicClient": false,
                "enabled": true
                }
}
!

Recuperar o CLIENT_ID

CLIENT_ID=$(curl -s -k \
        -X GET \
        -H "Content-Type: application/json" \
        -H "Authorization: bearer $ACCESS_TOKEN" \
        "https://${KEYCLOAK_SERVER}/auth/admin/realms/myrealm/clients" | python -c '
import json,sys,os;keycloak_data=json.load(sys.stdin)
CLIENTID=os.environ["INSTANCE_NAME"]
for c in keycloak_data:
    if c["clientId"]==CLIENTID:
        print c["id"]
        sys.exit()
')

Talvez isso ajude se você ainda precisar ou se alguém precisar.

Responder2

O projeto Keycloak está quase descontinuado, eles agora possuem o Identity Access Management (IAM) que é proprietário.

O Keycloak em si sempre foi quebrado e muitos dos endpoints REST não funcionam e retornam respostas sem sentido, como você pode ver por si mesmo, mesmo seguindo estritamente a documentação.

A resposta é que, como o Keycloak está quebrado, mesmo seguindo a documentação, é impossível fazer o que você deseja.

Meu conselho é que você tente as alternativas que puder encontraraqui.

informação relacionada