byo-software / steam-openid-connect-provider

Steam OpenID Connect Identity Provider (IdP)
MIT License
67 stars 24 forks source link

steam_id claim not present when integrating with keycloak #21

Closed SebastianKunz closed 9 months ago

SebastianKunz commented 1 year ago

I can successfully link my steam account to keycloak and all claims, which are requested via the steam api, are present in the issued access token. However the steam_id claim is missing. Does one have to do something, like mapping, in order for keycloak to include the steam_id in the token? I was not successfull and since you mentioned keycloak in the readme I wanted to ask for help.

Thanks

Tawmy commented 1 year ago

Hey Sebastian,

You have two ways around this issue:

1. You** can go into the Identity Provider settings and enable "Store tokens". Keycloak will then store the access token it got from Steam. If you also enable "Stored tokens readable", new users will get the broker client role read-token, with which they can read the Steam IdP token using the https://your_url.com/realms/your_realm_name/broker/your_idp_name/token. Existing users will need to be assigned this role manually. This token will include various profile data, like the Steam ID, profile URL, avatar URL, etc.

2. You can not bother with a separate endpoint and create an attribute mapper. This is the way I chose to do it personally. I went a bit further and enabled the experimental Keycloak feature "declarative user profiles". This feature allows you to remove the "first name" and "last name" attribute, and allows you to remove the requirement for setting the email address after login. I had to get around this issue somehow, that's what worked for me. If you choose to do this, you'll have to edit the profile JSON to remove the email requirement, it doesn't seem to be a toggle in the UI.

The declarative user profile feature also allowed me to create a new field "nickname" for the users. I then created two mappers in the Identity Provider. The first attribute importer maps the steam_id onto the username field. I do this because otherwise people's chosen nickname will be the Keycloak username, which can lead to conflicts if two users called themselves "Jack" on their profile. With this, the Steam ID will be the Keycloak username, avoiding any conflicts.

The second attribute importer maps the "nickname" attribute onto the "nickname" Keyloak user profile field, which we previously added on the declarative user profile.

After all this, they Keycloak token will have the SteamID and Nickname in it. If you needed any other fields, like the profile URL, you could similarly add that to the user profile and create a third mapper for it.

I hope this will be helpful for you.

Tawmy commented 1 year ago

If you go for 2., you can also consider leaving the firstName or lastName attribute in there while hiding it from the user and making it non-required. You can then create a third mapper mapping the nickname onto the lastName/firstName attribute. You'll have a mapper mapping the same property twice, which seems redundant, however the UI cannot currently filter for custom attributes from the declarative user profiles feature.

This means you would only be able to search for Steam IDs, not nicknames. With this "redundant" mapper, the Steam username will be the first name / last name, allowing you to search for it, even if it's otherwise not used in your client.

Oooor you can just replace the nickname attribute with the firstName/lastName one. Works as well, would just have the wrong property name, but you'd always be able to filter in the user list.

Trojaner commented 9 months ago

Closing as @Tawmy provided an extensive description for a workaround