How to find the user id and password for IBM API? - ibm-cloud

I am a beginner for IBM API. I just launched an IBM Natural Language Understanding service. However, what I got is the API key instead of user id and passwords. Like this:
{
"apikey": "••••••••••••••••••••••••••••••••••••••••••••",
"iam_apikey_description": "Auto generated apikey during resource-key operation for Instance - crn:v1:bluemix:public:natural-language-understanding:us-east:a/6514bcdaafbc465498a244edb484cbe5:53e5f23b-f255-4d6c-b48d-cfce09c975b1::",
"iam_apikey_name": "auto-generated-apikey-51f2d016-d3ec-46bc-8be7-496ae621983d",
"iam_role_crn": "crn:v1:bluemix:public:iam::::serviceRole:Manager",
"iam_serviceid_crn": "crn:v1:bluemix:public:iam-identity::a/6514bcdaafbc465498a244edb484cbe5::serviceid:ServiceId-d83a34de-5860-443a-817a-b3cb3fb44e2a",
"url": "https://gateway-wdc.watsonplatform.net/natural-language-understanding/api"
}
In the example below, it shows I need a user id and a password. Where can I find them? Thanks!
import json
from watson_developer_cloud import NaturalLanguageUnderstandingV1
from watson_developer_cloud.natural_language_understanding_v1 \
import Features, EntitiesOptions, KeywordsOptions
natural_language_understanding = NaturalLanguageUnderstandingV1(
username='username',
password='password',
version='2018-03-16')
response = natural_language_understanding.analyze(
text='IBM is an American multinational technology company '
'headquartered in Armonk, New York, United States, '
'with operations in over 170 countries.',
features=Features(
entities=EntitiesOptions(
emotion=True,
sentiment=True,
limit=2),
keywords=KeywordsOptions(
emotion=True,
sentiment=True,
limit=2)))
print(json.dumps(response, indent=2))

This is all explained in the getting started tutorial from the instance.
Click Show to view your credentials.
Copy the username, password, and url values.
Important: The tutorial uses service instance credentials to
authenticate to the Natural Language Understanding service. In some
regions, new service instances instead use IBM® Cloud Identity and
Access Management (IAM) tokens for authentication. Authenticate by
using the approach that is right for your region and service instance.
They mention differing authentication types by region - but they don't really specify which regions use which type.
It is pointed out in the release notes
29 May 2018
The service now supports a new API authentication process for service
instances created in Sydney (au-syd). IBM® Cloud is in the process of
migrating to token-based Identity and Access Management (IAM)
authentication. IAM uses access tokens rather than service credentials
for authentication with a service.
As of 29th of May only newly created instance in Sydney (au-syd) use a different authentication method. I'm not sure if there is a better way to find this information out besides crawling through release notes chronologically.
So if your instance was created in the Sydney (au-syd) region after the 28th May 2018 or other regions have since been moved over to this system you'll have to generate a token and pass it through instead.
Using basic auth to intially get the token
curl -k -X POST \
--header "Authorization: Basic Yng6Yng=" \
--header "Content-Type: application/x-www-form-urlencoded" \
--header "Accept: application/json" \
--data-urlencode "grant_type=urn:ibm:params:oauth:grant-type:apikey" \
--data-urlencode "apikey={api_key}" \
"https://iam.bluemix.net/identity/token"
Then using the token from response for further API calls.
curl -X GET \
--header "Authorization: Bearer {token}" \
"https://gateway.watsonplatform.net/discovery/api/v1/environments?version=2017-11-07"
Just keep in mind that you will need to refresh the token periodically.

We added support for IAM in version 1.3.3. Always make sure you are using the latest version.
With IAM you will replace username and password with an iam_apikey parameter from the apikey credential field.
import json
from watson_developer_cloud import NaturalLanguageUnderstandingV1
from watson_developer_cloud.natural_language_understanding_v1 \
import Features, EntitiesOptions, KeywordsOptions
natural_language_understanding = NaturalLanguageUnderstandingV1(
iam_apikey='the apikey value from your question',
url='https://gateway.watsonplatform.net/natural-language-understanding/api',
version='2018-03-16')
response = natural_language_understanding.analyze(
text='IBM is an American multinational technology company '
'headquartered in Armonk, New York, United States, '
'with operations in over 170 countries.',
features=Features(
entities=EntitiesOptions(
emotion=True,
sentiment=True,
limit=2),
keywords=KeywordsOptions(
emotion=True,
sentiment=True,
limit=2)))
print(json.dumps(response, indent=2))

Looks like your app needs to use the API key there to request a bearer token from the Identity and Access Manager, according to the instructions at https://github.com/watson-developer-cloud/node-sdk/blob/master/README.md#authentication and https://console.bluemix.net/docs/services/watson/getting-started-iam.html#iam .

Related

How do I set up a Google Cloud Function with Authentication?

Disclaimer: I'm completely new to Google Cloud Functions and serverless functions in general.
I've set up a basic Google Cloud Function, set it to HTTPS trigger and Require Authentication, and given the service account and my account the cloud function invoker role.
However, whenever I use Postman to sent an HTTP request to the function using my oauth2 token, I get a 401 Unauthorized error.
I've also followed the steps here: https://cloud.google.com/functions/docs/securing/authenticating
to create and download the service account key and make an HTTP request using cURL and get the same error.
How do I need to set this up so that authorized users can send HTTP requests to this function?
Here's what I'm doing:
$gcloud auth login (to log in with my account with cloud invoker permission)
$curl https://my-trigger-url \ -H "Authorization: bearer $(gcloud auth print-identity-token)"
Guillaume found the solution:
My cURL syntax to trigger the Cloud Function needed the -H "Authorization: bearer $(gcloud auth print-identity-token)" before the URL instead of after, which is the opposite of Google's own documentation.
Thanks for your help.

Getting Users and groups from Keycloak

I have a web application secured by Keycloak. Now I want to read all the security groups and users from keycloak in my application. Is it possible?
Keycloak has a very good documentation around the APIs.
I believe you are looking to get all the groups and users from the Keycloak. It could be as straightforward as calling any REST APIs.
You can follow this link to get all the groups from the Keycloak.
And this link to get the users based on the given search criteria.
But I would be wary of the performance implication it might have calling these APIs. Make sure to use pagination and appropriate filters for getting users.
Also, if you want, you can write a custom extension in Keycloak to serve your purpose. You can follow this link for it.
I could get the access token using the client secret key using the curl command from command line.
$curl -X POST -d "client_id=my_client" -d "username=username" -d "client_secret=c957b0ba-c421-4021-8433-764aa2fwes72" -d "grant_type=client_credentials" HOST/auth/realms/my_realm/protocol/openid-connect/token
I could also get the list of users after getting the access token
$curl -X GET HOST/auth/admin/realms/my_realm/users -H "Authorization: Bearer access-token" -H 'cache-control: no-cache'
Now, I'm thinking how can I do this from my web application.

Keycloak impersonation API not implemented

I've been trying to use the Keycloak Impersonation API (semi-recent addition) to get an access token for another user. I have created a semi-successful CURL request based on the docs and another StackOverflow question. The CURL request (below) returns a 501 Not Implemented and I am trying to figure this out. If it would be another error I would assume I am doing something incorrectly, but this appears to be at least partially correct.
curl --verbose -X POST "http://localhost:8081/auth/realms/master/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "client_id=admin-cli" \
-d "requested_subject={TARGET_USER_ID}" \
-d "subject_token={USER_MANAGER_TOKEN}"
My workflow so far has been to get the Keycloak master realm "admin" user's access token (successful) and use that in the impersonation request, along with the target user's Keycloak ID. Am I doing something wrong or missing a step?
I haven't changed any Keycloak permissions, is this required?
From my understanding and the documentation, impersonation is currently supported and enabled by default in Keycloak v5 - Sever Installation. However, another article (Keycloak v5 - Token Exchange) seems to indicate that the feature is disabled by default; could this be why I am getting the 501 Not Implemented?
EDIT: #qdivision mentioned that the Token Exchange needs to be enabled for this to work. However, we are using the jboss/keycloak Docker image and I am wondering where I should add the profile.properties file to enable this feature?
Impersonation is enabled by default, Token Exchange is not.
To enable start the server with -Dkeycloak.profile=preview or -Dkeycloak.profile.feature.token_exchange=enabled as mentioned in the docs
https://www.keycloak.org/docs/latest/securing_apps/index.html#_token-exchange

How to obtain the authorization code required for User Credentials through the cURL's command line

I trying to use GCS "User Credentials" to connect to Google cloud storage using libcurl library.
"User Credentials" authentication needs Client Id & Secret key to connect to GCS, but in this process Authentication Code also needs to be generated.
I need to generate this Authentication code using cURL.
Can anyone help me ??
The Client ID you mentioned is the same as the Authentication ID and can only be generated from either the Cloud Console's Credentials Page or via the OAuth 2.0 Playground.
If you are trying to generate an Access Token (OAUTH2_TOKEN), you will need to complete an authentication flow to authorize requests as a user. Cloud Storage uses OAuth 2.0 for API authentication and authorization.
Here's what you need to do to get an authorization access token from the OAuth 2.0 Playground:
Select & authorize APIs (Cloud Storage)
Select the scope for the APIs you would like to access or input your own OAuth scopes, e.g.: https://www.googleapis.com/auth/devstorage.read_write
Then click the "Authorize APIs" button
Once you've got the Authorization Code click the "Exchange authorization code for tokens" button, you will get a refresh and an access token which is required to access OAuth protected resources.
Grab the Access Token to use in your cURL command
Then configure your request to Cloud Storage API by constructing your HTTP request like so (upload):
curl -X POST --data-binary #[OBJECT_LOCATION] \
-H "Authorization: Bearer [OAUTH2_TOKEN]" \
-H "Content-Type: [OBJECT_CONTENT_TYPE]" \
"https://www.googleapis.com/upload/storage/v1/b/[BUCKET_NAME]/o?uploadType=media&name=[OBJECT_NAME]"
You can have a look at this Cloud Storage upload example in our public docs to guide you with constructing a request and testing it out.
Hope this helps.

Keycloak - How to request a token with a custom lifespan?

Context: We are using Keycloak to secure our APIs by usually passing tokens through Authorization Headers. However, these APIs also allow users to download files (for instance: https://api.service.io/users.xlsx).
To use these "download endpoints", our web client applications pass users' token via query strings. (e.g. https://api.service.io/users.xlsx?accessToken=${bearerToken})).
Problem: Passing tokens via query string has several security flaws (browser history, ...). Therefore we would like to pass a very short-lived token (e.g. lifespan of 15sec) instead of the normal one (lifespan of 300sec by default).
Question: How could we request a different token from Keycloak API (for instance, /realms/#{realm_id}/protocol/openid-connect/token) by:
providing the normal access token (not credentials);
and specifying a different lifespan ?
After reading Keycloak's source code, it appears this is not possible (version 3.4.2.Final) to ask for a specific lifespan at runtime.
However, I developed a Keycloak Custom REST endpoint to do that. https://github.com/looorent/keycloak-configurable-token-api
When this JAR file is deployed in Keycloak, you can ask for a given lifespan at runtime. For example:
$ curl -X POST -d '{ "tokenLifespanInSeconds": 20}' -H "Content-Type: application/json" -H "Authorization: Bearer <user-access-token>" http://auth.service.io/auth/realms/a-realm/configurable-token