How to get a Bearer access token for Service Accounts - oauth-2.0

I have generate credentials for a service account like this:
f = file(settings.SERVICE_ACCOUNT_PKCS12_FILE_PATH, 'rb')
key = f.read()
f.close()
credentials = client.SignedJwtAssertionCredentials(settings.SERVICE_ACCOUNT_EMAIL, key, scope=settings.GROUPS_SCOPE, sub=settings.ADMIN_DOMAIN_EMAIL)
print 'credentials : '+str(credentials.to_json())
the print display the credentials in json format :
{"private_key": "MIIGwAIBAzCCBnoGLUn09Ywa1l7G8XC2SgA9eDhXAdKw4DAh...83J+6iAgIEAA==", "id_token": null, "token_uri": "https://accounts.google.com/o/oauth2/token", "token_response": null, "client_id": null, "scope": "https://www.googleapis.com/auth/admin.directory.group", "token_expiry": null, "_class": "SignedJwtAssertionCredentials", "refresh_token": null, "_module": "oauth2client.client", "private_key_password": "notasecret", "access_token": null, "service_account_name": "xxx#developer.gserviceaccount.com", "invalid": false, "assertion_type": null, "kwargs": {"sub": "username#domain.com"}, "client_secret": null, "revoke_uri": "https://accounts.google.com/o/oauth2/revoke", "user_agent": null}
This generate a private key ans access token that is null.
Is there a class that handels REST request specified here to get the access token ?

You can use access_token = credentials.get_access_token()
https://oauth2client.readthedocs.io/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2Credentials.get_access_token

Related

Keycloak how to obtain RPT

I'm trying to fetch all the permissions from Keycloak, ie all resources and scopes that a user has access to.
Basically, I want to fetch an RPT from Keycloak, with permissions shown as on Keycloak REST API docs and the below image
Unfortunately, the docs are either confusing, or the way of Requesting a RPT isn't shown. This example is all under RPT, and moving on, the docs just explain how to further introspect the token.
How can you obtain this token (anything that contains the permissions like in the sample token actually) from Keycloak?
You may want to try something like this:
USER=test
PASS=test
CLIENT_ID=test
CLIENT_SECRET=your-client-secret
RESULT=`curl -s --data "grant_type=password&client_id=${CLIENT}&client_secret=${CLIENT_SECRET}&username=${USER}&password=${PASS}" http://localhost:8080/realms/master/protocol/openid-connect/token`
ACCESS_TOKEN=`echo $RESULT | jq -r .access_token`
RPT_RESULT=`curl -s -H "Authorization: Bearer ${ACCESS_TOKEN}" --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket&client_id=${CLIENT}&audience=${CLIENT}" http://localhost:8080/realms/master/protocol/openid-connect/token`
echo $RPT_RESULT | jq -r .access_token | cut -d "." -f2 | base64 -d | jq
This retrieves an access token first and then queries an RPT.
This should give you an output like this:
{
"exp": 1643134734,
"iat": 1643134674,
"jti": "f60caba8-8f20-43f0-9054-6389f998032c",
"iss": "http://localhost:8080/realms/master",
"aud": "test",
"sub": "18cce3e6-e3a0-4be9-a1ff-6635adf5928b",
"typ": "Bearer",
"azp": "test",
"session_state": "539a81bf-aa27-4ce4-911a-405f5a2c90ac",
"acr": "1",
"realm_access": {
"roles": [
"create-realm",
"default-roles-master",
"offline_access",
"admin",
"uma_authorization"
]
},
"resource_access": {
"master-realm": {
"roles": [
"view-identity-providers",
"view-realm",
"manage-identity-providers",
"impersonation",
"create-client",
"manage-users",
"query-realms",
"view-authorization",
"query-clients",
"query-users",
"manage-events",
"manage-realm",
"view-events",
"view-users",
"view-clients",
"manage-authorization",
"manage-clients",
"query-groups"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
},
"test-realm-realm": {
"roles": [
"view-identity-providers",
"view-realm",
"manage-identity-providers",
"impersonation",
"create-client",
"manage-users",
"query-realms",
"view-authorization",
"query-clients",
"query-users",
"manage-events",
"manage-realm",
"view-events",
"view-users",
"view-clients",
"manage-authorization",
"manage-clients",
"query-groups"
]
}
},
"authorization": {
"permissions": [
{
"rsid": "9f708183-5aa3-4a8a-96fd-5be9aef5427d",
"rsname": "Default Resource"
}
]
},
"scope": "profile email",
"sid": "539a81bf-aa27-4ce4-911a-405f5a2c90ac",
"email_verified": false,
"preferred_username": "admin"
}

Twitter OAuth 1.0 "215 Bad Authentication Data" error when requesting token

My use case is 3-legged auth for my current business to get some impression data from Twitter. This stuff was a breeze on LinkedIn but I'm falling at the first hurdle with Twitter, having followed docs & videos I'm still running into a "Bad Authentication Data" error when getting an access token.
I've snipped the callback, consumer key and token, but the consumer key is the API key from my Twitter app and the token is the Access Token from the same. Below is the json. none, signature and timestamp I got auto generated by postman. Any pointers?
{
"name": "get_access_token",
"properties": {
"activities": [
{
"name": "Web1",
"type": "WebActivity",
"dependsOn": [],
"policy": {
"timeout": "7.00:00:00",
"retry": 0,
"retryIntervalInSeconds": 30,
"secureOutput": false,
"secureInput": false
},
"userProperties": [],
"typeProperties": {
"url": "https://api.twitter.com/oauth/request_token",
"method": "GET",
"headers": {
"OAuth": "oauth_nonce=\"wErUbiAbmCi\", oauth_callback=\"https%3A%2F%2F<snipped>\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1613748394\", oauth_consumer_key=\"<snipped>", oauth_signature=\"hMnZtN5hT5KHRcyrxz8xis33C1c=\", oauth_version=\"1.0\", oauth_token = \"<snipped>\""
}
}
}
],
"annotations": []
}
}
The OAuth headers need to be sorted alphabetically. The documentation is here.

IdentityServer4 Invalid authorization code{"code":

I am getting Invalid authorization code{"code": "MyTestCode"},
Here is more detailed error:
Invalid authorization code{"code": "MyTestCode"}, details: {"ClientId": "AuthorizationCodeClientFlow", "ClientName": "Authorization Code Client", "GrantType": "authorization_code", "Scopes": null, "AuthorizationCode": "MyTestCode", "RefreshToken": null, "UserName": null, "AuthenticationContextReferenceClasses": null, "Tenant": null, "IdP": null, "Raw": {"grant_type": "authorization_code", "code": "MyTestCode", "redirect_uri": "https://localhost:5000/oauth/callback", "client_id": "AuthorizationCodeClientFlow"}, "$type": "TokenRequestValidationLog"} <s:IdentityServer4.Validation.TokenRequestValidator>
I am testing using Postman
This is client generated from this code :
{
ClientName = "Authorization Code Client",
ClientId = "AuthorizationCodeClientFlow",
AllowedGrantTypes = GrantTypes.Code,
ClientSecrets =
{
new Secret("AuthorizationCodeClientFlowSecret".Sha512())
},
AllowedScopes =
{
"all"
},
RedirectUris =
new List<string> {
"https://localhost:5000/oauth/callback"
},
AllowOfflineAccess = false,
AccessTokenLifetime = 60
};
https://localhost:5105/oauth/authorize works fine. I get error in https://localhost:5105/oauth/token step. When I validate request like that:
var form = (await _httpContextAccessor.HttpContext.Request.ReadFormAsync()).AsNameValueCollection();
var validationResult = await _requestValidator.ValidateRequestAsync(form, clientResult);
if (validationResult.IsError)
{
return new IdpTokenResponse
{
Custom = new Dictionary<string, object>
{
{ "Error", validationResult.Error },
{ "ErrorDescription", validationResult.ErrorDescription }
}
};
}
You need to take the authorization code that you receive from the initial authentication request and then take it and pass it along when you get the token from the token endpoint.
one unrelated thing is that you should always ask for the openid scope when you authenticate against IdentityServer, All or "" is not valid.

not able to get photo from graph api from SPA front end web app

I am using ADAL js to authenticate user and i am able to authenticate user successfully. I am able to fetch a token for graph api and read user profile with following url.
GET
https://graph.microsoft.com/v1.0/me
But i am not able to read user profile picture:
https://graph.microsoft.com/v1.0/me/photo/$value
I get the following error
Object { code: "NoPermissionsInAccessToken", message: "The token contains no permissions, or permissions can not be understood.", innerError: {…} }
I have set the required permissions:
Is there any way i can check why i am able to fetch profile but not photo.
Content of JWT sent in header before it received 401 error:
{
"typ": "JWT",
"nonce": "IenxIPCU1ue14Z9bIIxEidRBBCTnL52w4Q",
"alg": "RS256",
"x5t": "huN95IvPf34GzBDZ1GXGirnM",
"kid": "huN95hq34GzBGXGirnM"
}
Body of JWT token:
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/6f1dc6d4-8e90-4593/",
"iat": 1596560469,
"nbf": 1596560469,
"exp": 1596564369,
"acct": 1,
"acr": "1",
"aio": "ATQAy/8QAAAAf64iQ9pAkP+bk/JnXpSNXFPVFqvW/urra8A2QueWm2xaJZM+",
"altsecid": "5::100320A47F8DD5",
"amr": [
"wia"
],
"app_displayname": "graphdemo-dev",
"appid": "dsfkj32-4350-44a4-dd33-f45b7172b0cd",
"appidacr": "0",
"email": "email#domain.com",
"family_name": "faily",
"given_name": "given",
"idp": "https://sts.windows.net/deff24bb-2089-4400378b2/",
"in_corp": "true",
"ipaddr": "70.50.13.18",
"oid": "dskfs77s-5bc6-4fbe-b59a-11fbc2",
"platf": "3",
"puid": "A9BDE43D",
"scp": "profile User.Read User.Read.All User.ReadBasic.All User.ReadWrite User.ReadWrite.All",
"sub": "r4-9Ra9nHTjU-g1PvuXwh18",
"tenant_region_scope": "NA",
"tid": "d4-8e90-4599-af70-13a4289b3",
"unique_name": "email#domain.com",
"uti": "MDGPXbP3lUJMyAA",
"ver": "1.0",
"xms_tcdt": 8700342
}
Note: I removed and updated confidential data with random chars.
When i tried on Graph Explorer:
Need admin approval
Graph explorer (official site)
microsoft.com
Graph explorer (official site) needs permission to access resources in your organization that only an admin can grant. Please ask an admin to grant permission to this app before you can use it.
import AuthenticationContext from 'adal-angular/lib/adal.js';
// KPMG
const config = {
tenant: process.env.VUE_APP_AZUREAD_TENANTID,
clientId: process.env.VUE_APP_AZUREAD_CLIENTID,
cacheLocation: process.env.VUE_APP_CACHE_LOCATION,
redirectUri: process.env.VUE_APP_REDIRECT_URI
};
export default {
authenticationContext: null,
/**
* #return {Promise}
*/
initialize() {
this.authenticationContext = new AuthenticationContext(config);
return new Promise((resolve, reject) => {
if (this.authenticationContext.isCallback(window.location.hash) || window.self !== window.top) {
// redirect to the location specified in the url params.
this.authenticationContext.handleWindowCallback();
}
else {
// try pull the user out of local storage
const user = this.authenticationContext.getCachedUser();
if (user) {
this.authenticationContext.config.extraQueryParameter = 'login_hint=' + user.userName;
resolve();
}
else {
// no user at all - go sign in..
this.signIn();
}
}
});
},
I use below code to get graph api token
acquireGraphApiToken() {
return new Promise((resolve, reject) => {
this.authenticationContext.acquireToken('https://graph.microsoft.com', (error, graphApiToken) => {
if (error || !graphApiToken) {
this.signOut();
return reject(error);
} else {
return resolve(graphApiToken);
}
});
});
},
For Microsoft Graph explorer, you need to sign in with an admin account and do the admin consent like this:
Do the admin consent:
And from the screenshot above, you can see the access token. After you finish the admin consent, you can decode the access token to see if it includes the required permissions.
For you own Azure AD application, I see that you have done the admin consent based on your screenshot. It's hard to say where the problem is. So my suggestion is to try the admin consent endpoint:
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/v2.0/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
&scope=
https://graph.microsoft.com/calendars.read
https://graph.microsoft.com/mail.send
Access this url in a browser using an admin account and finish the consent. If the issue still exists, you can create a new Azure AD application and only add the required permission User.Read (Don't add other permissions).

How to use MapJsonSubKey with json array

I'm using the oauth2 flow in an MVC application. I can be redirected to the provider to challenge the user and password and I can get access token to be used for the API call
once I made the API call I can retrieve the info but the response is a JSON that contains an array
how can I use the MapJsonSubKey to map the email from the below JSON?
{
"ErrorList": null,
"Status": 1,
"UserDetailList": [
{
"Email": "pippo.pluto#xxx.com",
"FirstName": "pippo",
"LastName": "pluto",
"PersonId": "pippo.pluto#xxx.com",
"ProfilePhoto": 1,
"ProfilePhotoPath": null,
"Status": 100,
"Title": null,
"UpdatedDate": "/Date(1561120073327+0000)/",
"UserGUID": "8f643f10-0559-4e34-972d-52f41a4b9fcc",
"UserId": 20,
"UserName": "ca9ba551-9347-45b3-a926-c9bf361252e0"
}
]
}
if I use this code
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier,"Id");
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "Name");
options.ClaimActions.MapJsonKey("urn:infor:status", "Status");
options.ClaimActions.MapJsonSubKey("urn:infor:uname", "UserDetailList[]", "Email");
and in the cshtml, i use this
#User.FindFirst(c => c.Type == "urn:infor:uname")?.Value
i cannot see any value in the page

Resources