Not getting all profile informations when verifying a google token authenticity - ruby-on-rails

I'm using omniauth on client-side to connect with a google account. Everything is working well, I'm able to get the id_token and some more informations such as the email, name, family_name, given_name etc...
Here is how I configured the provider in app/config/initializer/omniauth.rb :
provider :google_oauth2, ENV['GOOGLE_ID'], ENV['GOOGLE_SECRET'], scope: "profile,email"
Then, as a test, to verify the authenticity of the id_token, using Postman I send a POST request such as:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=x
replacing x by the id_token I got on my client
I get a valid answer such as :
{
"iss": "accounts.google.com",
"at_hash": "xxx-xxx",
"aud": "xxx-xxx.apps.googleusercontent.com",
"sub": "xxx",
"email_verified": "true",
"azp": "xxx-xxx.apps.googleusercontent.com",
"email": "xxx#gmail.com",
"iat": "xxx",
"exp": "xxx",
"alg": "xxx",
"kid": "xxx"
}
When I connected with my client, I allowed the application to access my profile informations and my email, and I've been following this tuto:
https://developers.google.com/identity/sign-in/web/backend-auth
who says :
// These seven fields are only included when the user has granted the "profile" and
// "email" OAuth scopes to the application.
"email": "testuser#gmail.com",
"email_verified": "true",
"name" : "Test User",
"picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
"given_name": "Test",
"family_name": "User",
"locale": "en"
I can't figure out why I'm unable to get the 5 last fields
I'm working on an API and I'd like my API to be able to fill a User model by itself, only by getting the id_token.
I'm able to get those informations on the client-side but I think this is not the client job to send this extra informations to my API right?

Token calls don't include profile info... for that you muse use:
https://www.googleapis.com/plus/v1/people/me/openIdConnect?access_token=YOUR_ACCESS_TOKEN

Since you are doing this with ruby there are 2 things i can suggest trying
Try adding your scopes as an array ["profile", "email"]
Add an extra parameter fetch_basic_profile from here

Related

Azure AD OAuth Token Claim - Populate DisplayName attribute for Application Users

When I request an OAuth token from Azure AD for an application user (using a client_id and client_secret) targeting the correct resource audience (target application), I don't know how to get Azure AD to populate a claim for the client's DisplayName attribute (primarily for an application client, but also users should work too) in Azure AD.
POST /<tenant_id>/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=<client_id>&resource=<target_aud_app_uri>&client_secret=<client_secret>
{
"typ": "JWT",
"alg": "RS256",
"x5t": "xxx",
"kid": "xxx"
}.{
"aud": "<target_aud_app_uri>",
"iss": "https://sts.windows.net/<tenant_id>/",
"iat": 1619676176,
"nbf": 1619676176,
"exp": 1619680076,
"aio": "xxx",
"appid": "<client_id>",
"appidacr": "1",
"idp": "https://sts.windows.net/<tenant_id>/",
"idtyp": "app",
"oid": "xxx",
"rh": "xxx",
"roles": [
"XXX"
],
"sid": "xxx",
"sub": "xxx",
"tenant_ctry": "AU",
"tenant_region_scope": "OC",
"tid": "xxx",
"uti": "xxx",
"ver": "1.0"
}.[Signature]
In the target application configuration in Azure AD, I've added all the optional claims it allows in the UI, and even tried adding 'display_name' via the manifest but it doesn't know how to pick it up. Is there a way to do this?
This question has been asked before.
This is possible under the Microosft.graph namespace only cannot be used for any custom app. In other words, only the ms graph api token has app_displayname claim. For the token of the application custom api, it is currently not possible to add the app_displayname claim, at least for now this is impossible.
I suggest you submit user voice, and I will vote for it.

Scopes vs Roles when accessing Resource Server with Keycloak as Authentication Server

I am using Keycloak as Authorization Server and setting up SPA (Public Client) that will be connecting to a REST service (Bearer-Only client / Resource Server).
As far as I understand, scopes are group of claims and claims are information about the subject (authenticated user). Scopes are passed at authentication step to the authorization server so that it will prompt the user to permit/deny access to those claims (user data / actions). In the case of third party client trying to access data from for example Facebook, scopes are permissions given by the user to the client to access user's data from Facebook. In case of Slack scope are used to allow / deny certain permissions for the third party client to perform operations on behalf of the user.
In my case where the resource server does not hold any user information but OAuth is used for authentication / authorization and will use the access token to get users group membership and possibly role to allow/deny access to the data on the resource server.
Correct me if I am wrong but scopes are used more for the user to allow third party client to access his/her information from OIDC provider, possibly get user information from the ID Token. On the other hand Roles / Groups that is set in the access token would be used to authorize the user to get data from the the resource server
For example here is the
Access Token:
{
"exp": 1612294865,
"iat": 1612294565,
"auth_time": 1612294524,
"jti": "e6c12a30-1b54-410a-81ba-ffe947dcebc9",
"iss": "http://localhost:8080/auth/realms/demo",
"aud": "rest-service",
"sub": "e49f2e27-4b47-492e-a714-2497d4f669f8",
"typ": "Bearer",
"azp": "js-console",
"nonce": "58faa6b8-a628-4b5a-8f0a-b33643812ef2",
"session_state": "2470b7b4-1587-43d5-8747-911b01398c3d",
"acr": "0",
"allowed-origins": [
"http://localhost:8000"
],
"resource_access": {
"rest-service": {
"roles": [
"user"
]
}
},
"scope": "openid email profile",
"email_verified": false,
"preferred_username": "test",
"group": [
"/my-group"
]
}
ID Token
{
"exp": 1612294865,
"iat": 1612294565,
"auth_time": 1612294524,
"jti": "c3242eb4-9047-4913-9ac6-be3b4e2b5745",
"iss": "http://localhost:8080/auth/realms/demo",
"aud": "js-console",
"sub": "e49f2e27-4b47-492e-a714-2497d4f669f8",
"typ": "ID",
"azp": "js-console",
"nonce": "58faa6b8-a628-4b5a-8f0a-b33643812ef2",
"session_state": "2470b7b4-1587-43d5-8747-911b01398c3d",
"at_hash": "5hOJUzWD9H2DOuYCEnc6fQ",
"acr": "0",
"email_verified": false,
"preferred_username": "test"
}
The audience(aud) for the ID token is set to the Client (js-console) and returns just some user information and really only needs openid scope. The access token aud is set to the rest service that will consume the access token and retrieve the roles and group information.
This is a different usage of OAuth which in this case the user doesn't need to consent to anything but will authenticate and use the access token to get information based on the group membership.
Is my understanding is correct?
Thanks!

Access Token contains almost all information from Identity Token

The tokens below are returned upon initial token request with Azure AD B2C. access_token contains most information that id_token contains.
My questions are that:
1 Since access_token contains most information that id_token contains, what scenario can access_token be used in place of id_token? what scenario must id_token be used instead of access_token?
2 What are the rules regarding use of both access_token and id_token in general?
Result upon initial token request
{
"access_token": "access_token",
"token_type": "Bearer",
"expires_in": "3600",
"refresh_token": "refresh_token",
"id_token": "id_token"
}
Below is the decoded token for the respective token:
Please note that access_token contains most information from id_token, including user information.
access_token
{
"iss": "url",
"exp": 1550539339,
"nbf": 1550535739,
"aud": "audience ",
"idp": "LocalAccount",
"sub": "guid",
"name": "user#email.com",
"emails": [
"user#email.com"
],
"tfp": "B2C_1_ROPC_Auth",
"ver": "1.0",
"iat": 1550535739,
"azp": "guid"
}
id_token
{
"iss": "url",
"exp": 1550539339,
"nbf": 1550535739,
"aud": "audience ",
"idp": "LocalAccount",
"sub": "guid",
"name": "user#email.com",
"emails": [
"user#email.com"
],
"tfp": "B2C_1_ROPC_Auth",
"ver": "1.0",
"iat": 1550535739,
"auth_time": 1550535739,
"at_hash": "access_token hash"
}
Update
Further to question 1 above:
Since access_token contains most information that id_token contains, can access_token be used instead of id_token? That is, when id_token must be used instead of access_token?
I will take google as a example,
1) let say you want to implement social login where u mostly need fields like email, 'first_name', 'last_name'., these fields are mostly available in id_token. so id_token is perfect suitable for authentication.
2) later u need to fetch google contacts of the login user., In such scenarios u can't get contacts of the user in id_token. this is where access_token comes, though u won't have the contacts in access_token but all permission to fetch the contacts.
An ID token is intended for authentication. It is represented as a JSON Web Token (JWT) that contains claims about an authentication event including the identity information for a resource owner. The ID token is intended for a client application (a single-page app) and its aud (audience) claim contains the OAuth 2.0 client_id of the client application.
An access token is intended for access by clients to resources that are owned by a resource owner. It is represented as either a JWT (e.g. Azure AD B2C represents an access token as a JWT) or an opaque token. The access token is intended for a resource application (e.g. an API app) and its aud claim contains the OAuth 2.0 client_id of the resource application.

Adal.js returns a token with invalid permission with a powerbi resource

I'm having issue authenticating with Azure Active Directory which is linked to a power BI service. I'm trying to get an access token so that I can access the power bi rest API.
If i use postman, I'm able to successfully use their OAuth2 login to retrieve a token that has the correct credentials to communicate with the power bi rest API.
However, when I try to do this with the adal.js the token is invalid. To simplify this to be able to reproduced, I based my project off
https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp-dotnet-webapi
You need to update window config in : \active-directory-javascript-singlepageapp-dotnet-webapi\TodoSPA\App\Scripts\app.js
window.config = {
instance: 'https://login.microsoftonline.com/',
tenant: <insert tenant>,
clientId: <insert clientid>,
postLogoutRedirectUri: window.location.origin,
cacheLocation: 'localStorage', // enable this for IE, as sessionStorage does not work for localhost.
endpoints: {
"https://api.powerbi.com": "https://analysis.windows.net/powerbi/api",
}
};
Workaround
I'm able to get the token via silent authentication where you have to hard code the username and password.
I followed this http://community.powerbi.com/t5/Developer/How-to-use-Power-BI-Rest-API-without-GUI-authentication-redirect/m-p/14218#M119 to create the request for silent authentication:
Post Url: https://login.windows.net/<tenant>/oauth2/token
Body:
password: <password>
username: <username>
client_id: <clientid>
client_secret: <secret>
grant_type: password
scope: openId
resource: https://analysis.windows.net/powerbi/api
I also validated that the account I used had the correct permission by using postman and authorization with OAuth2. The token I received had the correct permission for PowerBI.
Post Man Configuration
On postman, click on Authorization Tab -> Set Type to OAuth2.0 -> Get New Access Token:
The configuration you would use:
AuthUrl: https://login.microsoftonline.com//oauth2/authorize?resource=https://analysis.windows.net/powerbi/api
Access Token URL: https://login.microsoftonline.com//oauth2/token
Grant Type: Authorization Code:
Client ID:
Client Secret:
Go to https://dev.powerbi.com/apps to generate the clientID/ClientSecret and set the Redirect URL: https://www.getpostman.com/oauth2/callback
postman generated token:
{
"aud": "https://analysis.windows.net/powerbi/api",
"iss": "https://sts.windows.net/<id>/",
"iat": 1500464096,
"nbf": 1500464096,
"exp": 1500467996,
"acr": "1",
"aio": <value>,
"amr": [
"pwd"
],
"appid": <app_id>,
"appidacr": "1",
"family_name": "Sunderam",
"given_name": <userName>,
"ipaddr": "23.252.49.99",
"name": <name>,
"oid": <oid_id>,
"platf": "3",
"puid": <puid_id>,
"scp": "Content.Create Dashboard.Read.All Data.Alter_Any Dataset.Read.All Dataset.ReadWrite.All Group.Read Group.Read.All Metadata.View_Any Report.Read.All Report.ReadWrite.All",
"sub": <sub_id>,
"tid": <tid_id>,
"unique_name": <user_email>,
"upn": <user_email>,
"ver": "1.0",
"wids": [
<wid_id>
]
}
adal.js token
{
"aud": <aud_id>,
"iss": "https://sts.windows.net/<id>/",
"iat": 1501037728,
"nbf": 1501037728,
"exp": 1501041628,
"aio": <aio_id>",
"amr": [
"pwd"
],
"family_name": <name>,
"given_name": <name>,
"ipaddr": "23.252.49.99",
"name": ,"name"
"nonce": "b21969c3-ae73-4928-bcd0-e9c501f791e4",
"oid": <oid_id>,
"platf": "5",
"sub": <sub_id>,
"tid": <tid_id>,
"unique_name": <user_email>,
"upn": <user_email>,
"ver": "1.0"
}
Notice that the postman token has the scp, appid, and wids.
Any Advice appreciated,
Thanks,
Derek
You need to check the token via the request. For example, you can check it via the developer tools-Network tab(Chrome, F12).
And based on the token and code, the config seems incorrect. For the endpoints is the collection of {Endpoint-ResourceId} used for automatically attaching tokens in webApi calls.
You can use the config like below:
window.config = {
instance: 'https://login.microsoftonline.com/',
tenant: <insert tenant>,
clientId: <insert clientid>,
postLogoutRedirectUri: window.location.origin,
cacheLocation: 'localStorage', // enable this for IE, as sessionStorage does not work for localhost.
endpoints: {
"https://analysis.windows.net/powerbi/api": "https://api.powerbi.com",
}
};
More detail about this library, you can refer this link.

Refreshing tokens with GIDSignIn iOS

I am currently using google sign to authenticate users to my app, but am having problems with the id_token after it's been refreshed. I have the following variables set up. One is for the iOS client and one is for the server. This is following AWS examples. I am using AWS to access the server and therefore need to have a client id and web application id.
static let GOOGLE_CLIENT_ID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx7dde.apps.googleusercontent.com"
// Backend web application client ID
static let GOOGLE_WEB_APPLICATION_ID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx65ap.apps.googleusercontent.com"
When I first log in the application it works as expected. I get an id token back that has the following:
{
"iss": "https://accounts.google.com",
"at_h ash": "xxxxxxxxxxxxxxxxxxxxxx",
"aud": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx65ap.apps.googleusercontent.com",
"sub": "xxxxxxxxxxxxxxxxxxxxxx",
"email_verified": true,
"azp": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx7dde.apps.googleusercontent.com",
"email": "2222MyNewEmailIsHere#gmail.com",
"iat": 1475747692,
"exp": 1475751292
}
You can see that the "aud" matches the GOOGLE_WEB_APPLICATION_ID and the "azp" matches GOOGLE_CLIENT_ID.
However if I do a refreshTokensWithHandler like so:
GIDSignIn.sharedInstance().currentUser.authentication.refreshTokensWithHandler { (GIDAuthentication, error) in
self.googleAuth = GIDAuthentication;
self.completeGoogleLogin()
}
I get a problem with the response. The id token is being refreshed correctly and thus have a new id token. However the "aud" seems to be overwritten with the client id. This happens whether the token has expired or not.
{
"iss": "https://accounts.google.com",
"at_h ash": "xxxxxxxxxxxxxxxxxxxxxx",
"aud": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx7dde.apps.googleusercontent.com"",
"sub": "xxxxxxxxxxxxxxxxxxxxxx",
"email_verified": true,
"azp": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx7dde.apps.googleusercontent.com",
"email": "2222MyNewEmailIsHere#gmail.com",
"iat": 1475747692,
"exp": 1475751292
}
As you can see, the "aud" and the "azp" is the same in the second response. When I then go to make a request to the server it's complaining that the token can't be verified.
I am wondering if anyone else has experienced this? It seems like an issue with GIDSignIn maybe.

Resources