Get the user roles with the keycloak userinfo endpoint - keycloak

How can I get the the roles included in the reply of the userinfo endpoint in keycloak. I defined a "Role Mapping" for the user in keycloak. When I call the userinfo endpoint I get the fields like email name etc, but the roles are not included in the reply. When I call the auth endpoint I get the access_token and in the field scope has roles included. Here is the reply from the auth endpoint:
access_token" QJsonValue(string, "eyJhb...")
"expires_in" QJsonValue(double, 300)
"not-before-policy" QJsonValue(double, 0)
"refresh_expires_in" QJsonValue(double, 1800)
"refresh_token" QJsonValue(string, "eyJhb...")
"scope" QJsonValue(string, "profile email roles")
"session_state" QJsonValue(string, "20b48536-4b38-4aa6-9072-e8309833402e")
"token_type" QJsonValue(string, "bearer")
I also tried to call the userinfo endpoint with the attribute "scope=roles", but this didn't work.

As someone already mentioned, it's a bug. I heard it's fixed in latest version of keycloak.
I eventually fixed with this setting without upgrading to the fixed version of keycloak.
When you add User Realm Role, it will have "realm_access.roles" as Token Claim Name. You need to change it to "roles". Then it will show correctly within userinfo.

Should be this issue: https://keycloak.discourse.group/t/resource-access-claim-missing-from-userinfo-until-i-change-the-name/1238
When renaming the claim in Client Scopes -> roles -> Mappers -> realm roles/client roles, i.e. realm_access.roles to realm_accessy.roles (and setting Add to userinfo to ON), it is included in userinfo :-/

In the mapper page on Keycloak, there is a setting called Add to userinfo, that has to be enabled.

For those whose above answer didn't work, I have spent the whole day figuring it out.
Basically, you have to go to client Scopes--> roles --> then move to Mappers tab, select client roles Add to Id token, access token and userinfo on
Here is the Screenshot

Related

Determine if Keycloak User has TOTP enabled

I have a Single-Page Web-Application authenticating against Keycloak and letting Users enable TOTP in their Keycloak-Account-Page.
However I want the Client-Application to determine after login, if the authenticated User has 2-factor-authentication/TOTP enabled or not.
Is it possible to map this (boolean) information into the Tokens or userinfo Endpoint ... I haven't found any User Property, that contains this information.
The only Place I found it, was in Admin-REST-API /auth/admin/realms/{realm}/users/{uuid}, but the Client/End-user won't and shouldn't have access there:
{
...
totp: true,
}
I don't think this is possible without customization.
You may want to add a custom protocol mapper and check for totp like this:
keyclaokSession.userCredentialManager().isConfiguredFor(realm, user, OTPCredentialModel.TYPE)
Here is a video that explains the first steps.

Access Keycloak group attributes from Nodejs

I've got Keycloak setup and running with NodeJS.
I see you can create groups and assign attributes to those groups. Is it possible to access these attributes from the NodeJS application?
I can't even find the groups let alone their attributes.
Yes you can. But there is almost no official documentation on how to achieve this. You can return most keycloak attributes, groups and roles through the client mappers. By default none are configured.
To configure extra mappers: In the administration console, select the client and then the Mappers tab. That should bring you to a list of mappers.
You can add mappers here of different types. Once you add a mapper you can decide which calls to Keycloak from the client return the attribute(s), and what the name of the returned attribute is. The following screenshot includes a mapper that returns a dictionary of groups, with subgroups, separated by forward slashes. Your Node code will need to parse the returned JSON object.
All the information is returned in the keycloak token, which is a Javascript Web Token. In Node you can examine it by printing the token to the log. The keycloak-connect middleware stores tokens etc in an object on the request called kauth. The path to retrieve a list of groups specified by the configuration in the above screenshot is shown below. If you change the token claim name in the configuration, you will need to change the path in your NodeJS code accordingly. You will need to logout from your application and login again for changes to the mapper to work.
router.get('/', async function(req, res){
console.log(req.kauth.grant.access_token.content.groups) ..
}

Facebook Oauth2 - invalid scope id?

I'm trying to implement facebook login/autoregister for a website. There is a problem with the requested scopes.
First I have tried to use the "default" scope. According to the official documentation, it provides access to a subset of the UserData structure. It is documented here:
https://developers.facebook.com/docs/facebook-login/permissions/#reference-default
However, if I try to do this, then I get an error:
Invalid scope: default
I have also tried to use something basic first. For example, scope="id". Then I get this error:
Invalid scope: id
If I try scope="email first_name last_name middle_name name picture" then:
Invalid scope: first_name
The only that worked so far is scope="email", but that is not enough for auto registration.
Moreover, the documentations cleary says that "All permissions, except the Default Public Profile fields, require Facebook Login and Client OAuth Login enabled for your app to allow Users or Pages to grant your app these permissions." (you can read this on the top of https://developers.facebook.com/docs/facebook-login/permissions/ ). So it seems that the scopes are not invalid because I don't have Facebook Login enabled for my app. They are invalid for some other reason - maybe because the don't exist?
I wonder why are these scopes documented if they are invalid? And where can I find the valid ones?
Side note: it seems that Facebook does not follow RFC 6749. When there is an error, the Oauth2 server (https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2 more specifically 4.1.2.1 error response ). But Facebook does not do this. It displays a popup window on facebook.com instead, and if I press "OK" on that window, it enters an infinite loop and keeps displaying the same message again and again: "You are no logged in". (Why would I?)
UPDATE: Even though I used scope=email only, the /me api returned all fields, including first_name, last_name, email, and profile picture. So maybe those things are not scopes, but field names. But it is still unclear what scopes are available? The documentation still seems bad. It should clearly tell which terms are scopes, which are field names from data structures. And a complete list of scopes is still missing from the docs (or maybe there is a list, just I couldn't find it?)
The docs are indeed a bit misleading, but "default" is not a permission/scope, it just tells you want data you can get WITHOUT an additional permission. You can find the available permissions in the link of your question, if you just scroll to the top. Only that list is important, for the default fields there is a link "Default Public Profile Fields", but - again - no scope/permission is needed.
And yes, there is a big difference between scope and fields. For example, the email field can be used after authorizing with the email scope, but the birthday field requires authorization with the user_birthday permission. Fields can be found here, for example: https://developers.facebook.com/docs/graph-api/reference/v3.1/user

Identity Server - Identity/Resource scope - How can client get resource claims about the user

I have read Dominik's blog post on authentication vs permission modeling using Identity Server (https://leastprivilege.com/2016/12/16/identity-vs-permissions/). Since I am mostly using role based authorization, I am fine using IdentityServer as authentication/authorization endpoint for different client and apis.
My question is how to model Identity and Resource scopes properly? Can client know which roles are allowed for the user on specific resource? If yes, can client know only the user roles for requested resources scopes (and not all roles for all scopes).
As far as I understand the concept, if I request claims about the user via UserInfo endpoint, I am receiving claims which are filtered by claimTypes listed inside requested identity scopes. That means that if client requests roles scope (identity scope with role claimtype), UserInfo endpoint will respond with all role claims including other applications.
Let's take simple MVC example, where the MVC client communicates with API via REST.
MVC client (client) uses Cookie/OIDC Auth middleware and requests: ResponseType = "id_token token", Scope = "openid profile api".
The API (resource) uses IdentityServerBearerToken Auth middleware and demands: RequiredScopes = "api".
The client has UI elements which should be visible based on api role. How can the roles be accessed from client, since the UserInfo endpoint will only return identity scope based claims?
Should client ask the API (resource), which actions are possible? And based on the response show/hide UI elements?
Thank you for any help.
So things are different between IdentityServer3 and IdentityServer4. My example below is based on IdentityServer4.
You need to do a few of things:
define an IdentityResource that grants access to the role claim.
Include that new IdentityResource in the client's AllowedScopes
Have the client request your new IdentityResource as a scope.
So what I did was as follows:
Where I defined my resources:
new IdentityResource
{
Name = "roles",
UserClaims = { JwtClaimType.Role }
}
Defined my client as:
var client = new Client
{
// .. other stuff
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"roles"
}
}
And then used the the following in my javascript client:
new oidc.OidcClient({
// .. other stuff
scope: 'openid profile roles'
});
I was then able to see all the JwtClaimType.Role claims I'd added to the ClaimPrincipal in my javascript client.
You can put the roles in your id_token. Implement GetProfileDataAsync and add your roles when:
context.Caller == Constants.ProfileDataCallers.ClaimsProviderIdentityToken
or if you need them on the api you can also add them when:
context.Caller == onstants.ProfileDataCallers.ClaimsProviderAccessToken
If you make use of RequestedClaimTypes passed in the context you can filter out if a certain identity scope is requested or not.
For access tokens the resource scope matters (the claim types you specify on those scopes are put in the RequestedClaimTypes for all your requested scopes in the case of
context.Caller == Constants.ProfileDataCallers.ClaimsProviderAccessToken)
Both are called above if you ask for id_token token
The user info endpoint can be called by your api in case you use reference access token with openid scope (must be called otherwise you don't have any info) or want more claims than by default in the principal (coming from a jwt access token),
context.Caller == Constants.ProfileDataCallers.UserInfoEndpoint
(here the RequestedClaimTypes are the ones specified on the resource scopes your access token has access to..). You can also choose to include them in the id_token when the resource scope is part of the requested scopes, for example "openid myscope" where myscope is a resource (api for example), by enabling the 'AlwaysIncludeInIdToken' flag.
Fixed it, I needed to add the openid and profile scopes to the client;
AllowedScopes = new List<string>
{
"customAPI.read",
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
}

Salesforce API CALL issue

I'm testing the REST API,
I successfully called to https://naxx.salesforce.com/services/data/v29.0/sobjects/
It returns the expected result.
When I call to https://naxx.salesforce.com/services/data/v29.0/sobjects/Account/
It returns a (404) Not Found response.
I have replaced the "Account" placeholder with the logged user's email, nickname, email , also I have tried with access_token.id value but nothing works. The answer is always 404.
What should I use as "Account" value, and where can I get that information?
I'm following this documentation:
http://www.salesforce.com/us/developer/docs/api_rest/index_Left.htm#CSHID=quickstart_oauth.htm|StartTopic=Content%2Fquickstart_oauth.htm|SkinName=webhelp
Specifically the subtitle called "Get Basic Object Information".
I have the same problem with:
https://naxx.salesforce.com/services/data/v29.0/sobjects/Account/describe/
https://naxx.salesforce.com/services/data/v29.0/query?q=SELECT+name+from+Account
I have not the problem with:
https://naxx.salesforce.com/services/data/
https://naxx.salesforce.com/services/data/v29.0/
https://naxx.salesforce.com/services/data/v29.0/sobjects/
Thank you in advance.
Account is not placeholder text it is the actual name of an SObject type. That it returns a 404 response means your user account does not have access to Account records. You should check your users profile & license settings. The services/data/v29.0/sobjects/ request will return details of all the SObject types your user has access to. (so you'll find that Account is not in this list in your case)
I had a similar issue. I was able to access the object Account in the list of objects but was not able to retrieve the metadata. Seems that the documentation misses the parameter "sobjects" in the path. The correct URL is:
https://na1.salesforce.com/services/data/v20.0/sobjects/Account/describe/ -H "Authorization: Bearer token"
This can be confirmed through by trying the url:
https://na1.salesforce.com/services/data/v20.0/sobjects/Account
which lists the uses such as records, describe, listviews, etc. It may vary based on organization and if the user has permission, it is ideal that the developer hit the second URL and then obtain the correct base url to retrieve the metadata.