Calling external APIs through fiware orion context broker to validate using keyrock - fiware

I am a student working on a project and exploring viability of using fiware for that. So far I've learnt that to call external APIs we can use registrations for an entity to fetch dynamic data.
Here is the situation:
In my project, I am calling external APIs for fetching some data at frontend.
I want to add access control for users so that they are restricted from calling the APIs if not permitted. For this reason I am trying to find out a way such that keyrock can validate the requests so that I don't have to manually validate these external APIs. Since these aren't related to any entity I don't want to use registration for this purpose.
I intend to do user management through keyrock itself. Currently keyrock can restrict based on resources (i.e. URL path) of the application and permission. I am very confused at this point that if I add an API call at any page to fetch data from external API, how can I make use of keyrock access control in this situation.
Also, can I make orion call the external API somehow and make the data an entity?
Any help and hint is greatly appreciated. Thanks in Advance.

A registration is a contract to return a series of attributes connected to an entity, how that is connected to an external API is up to you. There is an annotated example in the NGSI v2 tutorials - the code is also available for NGSI-LD but the documentation for NGSI-LD needs updating to reflect certain recent changes and clarifications made in NGSI-LD 1.6.1.
Regardless of the version of NGSI you use, the steps to call an external API are the same.
Create a proxy service with a handler to deal with one or more NGSI endpoints - for NGSI-v2 this will usually be the batch endpoint /op/query, for NGSI-LD I would recommend /ngsi-ld/v1/entities/<id>.
Create a registration from your context broker to this proxy e.g. for NGSI-v2:
curl -iX POST \
'http://localhost:1026/v2/registrations' \
-H 'Content-Type: application/json' \
-d '{
"description": "Random Weather Conditions",
"dataProvided": {
"entities": [
{
"id": "urn:ngsi-ld:Store:001",
"type": "Store"
}
],
"attrs": [
"relativeHumidity"
]
},
"provider": {
"http": {
"url": "http://location/of/the/proxy/interface"
}
}
}'
Note that you can also pass additional custom information using custom headers or annotating the path of the URL or whatever.
Within the proxy code make a request to the third party API and convert the response back to NGSI format. The tutorial example explains how to connect to Twitter or Cat Facts as examples.
I want to add access control for users so that they are restricted from calling the APIs if not permitted.
This is purely a matter of placing a PEP proxy in front of the call to the registrant. Imagine a context broker request like this one to Kong:
curl -X GET \
http://localhost:8000/orion/v2/entities/urn:ngsi-ld:Store:001?options=keyValues \
-H 'Authorization: Bearer {{X-Access-token}}'
Either you place the PEP in front of the context broker (in which case the entity is only returned if you have appropriate permissions, or you place a PEP in front of your registrant webservice, in which case the attributes are only appended to the entity if you have appropriate permissions. Note that the context broker Registration needs to be configured to ensure that the Authorization header will be passed on to the registrant as well.

Related

How to check if IOTA is receiving data from device

I recently suspect I have configuration problem with the SOUTHBOUND traffic. Device already provisioned with IOTA. How do I check if the agent is receiving measurements?
First, try looking in the agent's log file, to discard errors. If you do not find anything, try changing the severity of the log file to a more comprehensive value like DEBUG.
I have never used this FIWARE IoT Agent, but with others like IoT Agent for the Ultralight if you configure the severity of the log file in DEBUG the reception of each message is shown.
If you need help to change the log file severity, start reading the agent configuration page here.
On the other hand, if you have your agent attached to an Orion context broker, you should be able to validate that you are receiving data, observing how your contexts change as you receive data. For this you have the Orion API.
EDIT:
All FIWARE agents shares a core library called node-lib and that component define interfaces to manage device provisioning and similar operations.
There are HTTP methods to create, fetch and delete devices and in particularly for updating a device. Check apiary blueprint here for more information.
As an example:
Getting all devices
curl -X GET [your_agent_host]:[port]/iot/devices
Update a device
curl -X POST [your_agent_host]:[port]/iot/devices/{device_id} -d
'{"attributes": [{
"object_id": "attr_id",
"name": "attr_name",
"type": "attr_type"} ...
]}'
I think there is no way to perform a partial update on a single device, you must specify all the attributes again.
Greetings and I hope I have been of some help!

Keycloak: Validate access token and get keycloak ID

I need to be able to do the following (with plain cURL & JSON server-side- no frameworks or Java):
Use a string representation of a Keycloak access token I have been given by a 3rd party to verify that the token is valid.
If the token is valid, get the Keycloak ID for that user.
How do I do this using plain old HTTP posts? I've found lots of Java examples but I need to know the raw HTTP POSTs and responses underneath.
Is it something like this to validate the token?
/auth/realms/<realm>/protocols/openid-connect/validate?access_token=accesstokenhere
What does this return in terms of data (sorry I currently have no test server to interrogate)?
Thanks.
The validate endpoint does not seem to work now. It used to return access token. I am using the keycloak 2.5.1 now. As mentioned in post by Matyas (and in the post referenced by him), had to use introspect token endpoint.
In my testing Bearer authentication did not work. Had to use Basic authentication header along with base64 encoded client credentials.
base64.encode("<client_id:client_secret>".getBytes("utf-8"))
The response from introspect endpoint is in JSON format as shared in post referenced by Maytas, has many fields based on type of token being introspected. In my case token_type_hint was set as access_token.
requestParams = "token_type_hint=access_token&token=" + accessToken
The response included required user details like username, roles and resource access. Also included OAuth mandated attributes like active, exp, iss etc. See rfc7662#page-6 for details.
Maybe you need this:
http://lists.jboss.org/pipermail/keycloak-user/2016-April/005869.html
The only one problem is that, introspect is not working with public clients.
The key url is:
"http://$KC_SERVER/$KC_CONTEXT/realms/$REALM/protocol/openid-connect/token/introspect"
You need to authorize your client e.g. with basic auth, and need to give the requester token to introspect:
curl -u "client_id:client_secret" -d "token=access_token_to_introspect" "http://$KC_SERVER/$KC_CONTEXT/realms/$REALM/protocol/openid-connect/token/introspect"

WSO2 IS 5.1.0 as OAuth/OIDC IdP response with different claims on UserInfo endpoint

Anyone know why if I make a call to /userinfo endpoint I obtain different JSON response? Specifically:
When I make a call with curl from command line, like $curl -k -H "Authorization: Bearer 2bcea7cc9d7e4b63fd2257aa31116512" https://localhost:9443/oauth2/userinfo?schema=openid I obtain as response the JSON: {"sub":"asela","name":"asela","preferred_username":"asela","given_name":"asela","family_name":"asela"}
If I make the call with a java client (a library that implement the Authorization Code Flow), when the client make the /userinfo call I have as response a JSON like {"sub":"asela#carbon"} without all other claims.
The claims for the service defined in WSO2 IS are the default ones. Thanks for any help.
I have tried this and got the same issue that you have faced. As I have mentioned in my previous comment, the issue occurs due to the claim mapping issue. Normally we get the user's attributes from the “http://wso2.org/claims” dialect. But when we call to OpenID userInfo endpoint, it will provide the user's attributes from “http://wso2.org/oidc/claim”. But all the claims in http://wso2.org/claims are not defined in http://wso2.org/oidc/claim. (Ex:Mobile, Address, Organization). So we have to define those required claims on http://wso2.org/oidc/claim dialect, if it is not defined.
You can check this claims from Identity Server Management console. To do this, Log into ManagementConsole > Main > List (under Claims)
Then you can go though the two claim dialects and add required claims to http://wso2.org/oidc/claim dialect. To add new claim, Goto ManagementConsile > Main > Add(under Claims) > Add new claim. See the attached screen shot of defining a sample claim. Here you need to map the exact Mapped Attribute & Claim Uri with the http://wso2.org/claims.
Hope this will helpful.
WSO2 IS normally returns the claims that are configured under the “http://wso2.org/oidc/claim” claim dialect. But the claim in the response should return normally. So make sure you have defined claim values in the user's profile. You can follow [1] & [2] for more details about this. Still you couldn't get the correct response, please attached your SP configurations and claim configurations for further analyze.
[1] http://xacmlinfo.org/2015/03/09/openid-connect-support-with-resource-owner-password-grant-type/
[2] http://shanakaweerasinghe.blogspot.com/2016/01/get-user-profile-for-oauth-token-using.html

Sending Events API (Output Adapter / Consumer resource) from FIWARE CEP: poor documentation

I'm trying to trigger an event sending to a consumer according to the DOCS for FIWARE CEP PROTON. There should be a resource in the API to which one can POST and that action should trigger sending output events to consumer.
However, it is not clear if mentioned resource is a literal or variable string. In docs it says: POST localhost:8080/application-name/consumer. I have tried using the name of CEP application I made and deployed to engine, name of the consumer used in that app and combinations with literals from the example, but not one of the resources exist.
Anyone ever used this resource from the API? It would be very helpful to debug with it.
I'm not sure about what your question is. Do you want to POST input events to proton? You can do that using:
POST http://{host}:8080/ProtonOnWebServer/rest/events
application/json
and your event:
{"Name": "event_type_name", "attr1": "value1", "attr2": "value2"}
ProtonOnWebServer is the name of my instance.
You can use any application like POSTER for Firefox.
Hope it helps! :)
If you want the CEP to send output events through REST, you need to add a consumer of type REST to your CEP application definition. In this REST consumer definition, you need to specify the REST service url.
Please note, that this REST service is not a CEP service. The CEP activates external REST service as a client.
In the CEP user guide, under Consumers -> Rest, you can see more details on the various attributes of this consumer definition.
From that user guide:
Rest – this adapter type is a REST client that POSTs events to an external REST
service upon detection of derived events. A Rest type consumer has the following
additional built-in parameters:
URL – the fully qualified URL of the REST service for event push operation
using the POST method.
ContentType – can be "text/plain", "application/xml", or "application/json". This is defined by the REST service.
AuthToken – an optional parameter, that when set, is added as an X-Auth-Token
HTTP header of the request.

Making REST API call using curl to Bluemix Predictive Modeling service

I would like to create HTTP GET request to REST API using the curl tool that comes with the Cloud Foundry command line interface (cf). The content/format of the request is described here, under "Retrieving a list of all currently deployed models:" subtitle. In short, the description gives me the url that I can make the request to, it also gives me the following "request example":
Content-Type: */*
Parameters:
Query Parameters:
accesskey: access_key from env.VCAP_SERVICES
I know how to retrieve all necessary parameters (i.e. the access keys, etc). The problem is that I am not sure how to interpret the above "request example" (is it header or body of the request?) and how to create curl command that will properly send the request.
I want to briefly describe what I have tried so far. When I try:
cf curl -X GET "http://{my_url}/model?accesskey={my_access_key}"
I always get the following response:
{
"code": 10000,
"description": "Unknown request",
"error_code": "CF-NotFound"
}
, when I try:
cf curl -X 'GET' http://{my_url}/model?accesskey={my_access_key}
, I think I actually get a response from the server:
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
Whenerver I try to use just "normal" curl (not the one that comes with the cf command line interface) the Bluemix Predictive Modeling service doesn't respond at all - the connection always times out. I'm not sure why, since Bluemix documentation says that any programming language can be used to make the REST API calls. In the future I would also like to use POST requests - an explanation of how to make one would be very helpful too.
Any help will be greatly appreciated.
You first need to "bind" an instance of the Predictive Model service to an app. When you have done it, you will have a "Show credentials" link below the app widget in your Bluemix dashboard. Click "Show credentials", and you will see a JSON object (which happens to be the VCAP_SERVICES value that Bluemix sets as environment variable for your app), for example:
{
"pm-20": [
{
"name": "Predictive Modeling-i6",
"label": "pm-20",
"plan": "free",
"credentials": {
"url": "https://ibmpmsrvus1.pmservice.ibmcloud.com:8443/pm/v1",
"access_key": "xxxyyyzzz"
}
}
]
}
(I have just removed my own credentials).
Finally for the Curl command, use the "url" above as root of your API, and add a query parameter "?accesskey=xxxyyyzzz" (whatever credentials you have on your own) to all API calls. For example, I add /model to my URL to query my list of models (none created):
curl -X GET "https://ibmpmsrvus1.pmservice.ibmcloud.com:8443/pm/v1/model?accesskey=xxxyyyzzz"
which returns
[]
(as I have not created any models). Note that you will likely need to quote the URL, since the access key contains characters that may mess up your shell command.
I explicitly used "-X GET": You will want to do "-X PUT" in some commands (PUT HTTP method), and most likely you can use "-d #" to upload a file as form data payload:
curl -X PUT -d #mymodelfile "https://..."