BenjaminFavre / keycloak-apple-social-identity-provider

Apple Social Identity Provider for Keycloak
Apache License 2.0
108 stars 53 forks source link

Keycloak 20.0.5 teamId and keyId not configurable from admin console #38

Open imaperson opened 1 year ago

imaperson commented 1 year ago

The admin console page does not display the teamId and keyId fields. To configure them, I had to update the identity provider using the REST API. I suspect this is a result of changes made to the Keycloak baseline. Other than this gotcha, this provider still seems to work.

medadadmin commented 1 year ago

@imaperson did you find a way to make the fields show again on UI ?

imaperson commented 1 year ago

@imaperson did you find a way to make the fields show again on UI ?

Negative, I used the REST API to get the JSON that represents the provider, hand edited the JSON to add "keyId" and "teamId", then used the REST API to PUT the modifications back in.

hvma411 commented 1 year ago

@imaperson could you please add some example how you did this? I'm not experienced keycloak user and I would like to be sure how to do it your way

imaperson commented 1 year ago

The REST API docs are pretty simplistic, but you should be able to figure out how to do other things with the following example. https://www.keycloak.org/docs-api/21.0.1/rest-api/index.html

I did everything on Linux with shell scripts. The following also assumes you're SSHed into the server running keycloak and that the API is accessible at localhost:8080. If those assumptions hold, the following should work.

Here's an example of the provider json that worked for me at least. Change values as desired:

{
      "alias": "apple",
      "internalId": "4d9f9018-fa5d-11ed-be56-0242ac120002",
      "providerId": "apple",
      "enabled": true,
      "updateProfileFirstLoginMode": "on",
      "trustEmail": false,
      "storeToken": false,
      "addReadTokenRoleOnCreate": false,
      "authenticateByDefault": false,
      "linkOnly": false,
      "firstBrokerLoginFlowAlias": "first broker login",
      "config": {
        "hideOnLoginPage": "false",
        "acceptsPromptNoneForwardFromClient": "false",
        "clientId": "<CLIENT-ID>",
        "keyId": "<KEYID>",
        "teamId": "<TEAMID>",
        "disableUserInfo": "false",
        "syncMode": "IMPORT",
        "clientSecret": "<CLIENT-SECRET>"
      }
    }

Replace , , , and with your values. For the next example, put the above in a file called apple.json

Here's some shell script snippets that I used to do the provider creation:

Get access token for next calls

export ACCESS_TOKEN=`curl "http://localhost:8080/realms/master/protocol/openid-connect/token" \
    -d "client_id=admin-cli" \
    -d "username=admin" \
    --data-urlencode "password=${KEYCLOAKPASSWORD}" \
    -d "grant_type=password" | jq -r .access_token`

Create the apple provider (be sure to replace )

curl -X POST "http://localhost:8080/admin/realms/<REALM-NAME>/identity-provider/instances" \
    -H "Content-Type: application/json" \
    -H "Authorization: bearer ${ACCESS_TOKEN}" \
    -d @apple.json

If it already exists and you need to update, something like this (be sure to replace )

curl -X PUT "http://localhost:8080/admin/realms/<REALM-NAME>/identity-provider/instances/apple" \
    -H "Content-Type: application/json" \
    -H "Authorization: bearer ${ACCESS_TOKEN}" \
    -d @apple.json
hvma411 commented 1 year ago

Thanks a lot for your help. I'll try it

Edit @imaperson your solutions works fine but even if I have this configuration already in keycloak I can't sign in with Apple. Apple verification is fine because I can sign in using apple id but after redirect to keycloak I can see message "We are sorry... Unexpected error when authenticating with identity provider"

imaperson commented 1 year ago

There is likely an error in the Keycloak log. What do you see there?

hvma411 commented 1 year ago

I can see two errors:

2023-05-25 19:25:39,127 ERROR [at.klausbetz.provider.AppleIdentityProvider] (executor-thread-3162) Unable to generate JWS: java.lang.NullPointerException: Cannot invoke "String.replace(java.lang.CharSequence, java.lang.CharSequence)" because "p8Content" is null ...a lot of java stuff here... ...a lot of java stuff here... ...a lot of java stuff here... 2023-05-25 19:25:39,740 WARN [at.klausbetz.provider.AppleIdentityProvider] (executor-thread-3162) Error response from apple: status=400, body={"error":"invalid_client"}

and

2023-05-25 19:25:39,741 ERROR [at.klausbetz.provider.AppleIdentityProviderEndpoint] (executor-thread-3162) Failed to complete apple identity provider oauth callback: java.lang.NullPointerException: Cannot invoke "org.keycloak.broker.provider.BrokeredIdentityContext.getIdpConfig()" because "context" is null ...a lot of java stuff here... ...a lot of java stuff here... ...a lot of java stuff here... 2023-05-25 19:25:39,746 WARN [org.keycloak.events] (executor-thread-3162) type=IDENTITY_PROVIDER_LOGIN_ERROR, realmId=some.realm.id.here clientId=some.client.id.here, userId=null, ipAddress=some.ip.address.here, error=identity_provider_login_failure, code_id=5290ab22-d8fa-438b-8c63-80879a3f0bf7

As I can understand from these errors there is something with p8Content which is clientSecret probably but I'm pretty sure it is in my configuration. Another thing which is strange for me that in the second error I can see clientId=some.client.id.here which is different than this one from my config (I see this in UI and in JSON). Is there any chance keycloack did some caching and I should clear it or restart it?

imaperson commented 1 year ago

Ah, the problem here is you're not using this apple provider, you're using this one https://github.com/klausbetz/apple-identity-provider-keycloak. Evidence for that is the package name of the apple provider at.klausbetz.provider.AppleIdentityProviderEndpoint. The configuration is very similar, but you need to use "p8Content": instead of "clientSecret": in the JSON above.

The clientId might be another problem. I'd recommend GETing the config back from keycloak and comparing the content you're PUTing/expecting. Something like this:

curl "http://localhost:8080/admin/realms/<REALM-NAME>/identity-provider/instances/apple" \
    -H "Authorization: bearer ${ACCESS_TOKEN}"
hvma411 commented 1 year ago

Lol, I don't know how could I forget to check which one I'm using. I was looking for some solution and probably many browser tabs caused my mistake 😂

Anyway, after changing clientSecret to p8Content it finally works even without taking care about clientId. Many thanks!