Anatomy of the FIWARE PEP Proxy – Wilma

The FIWARE PEP Proxy – Wilma is a key component of the IoT stack of the FIWARE ecosystem. The proxy is used for securing REST APIs, effectively introducing authentication and authorization as an aspect to existing HTTP-based services.

Architecture

The PEP Proxy is a compact NodeJS service. It intercepts incoming HTTP/HTTPS calls, checking the validity of the included OAuth2 token and verifies whether the associated principal can perform the action (HTTP method) to the resource (HTTP URL) specified in the call. In short, it operates as an identity service for OAuth2 bearer-only endpoints and adds HTTP-based authorization verification.

The PEP Proxy makes certain assumptions regarding its deployment environment:

  • The availability of the FIWARE Keyrock IDM and an existing service account bound to the PEP Proxy.
  • In case the PEP Proxy performs authorization checks on the incoming calls, an instance of the AuthZForce service is used for storing and verifying access policies.
There exist 2 distinct interaction scenarios in which the proxy is involved:
  • The PEP proxy authenticates itself to the IDM using its service credentials (attributes config.username & config.password found in config.js). The proxy username & password must be registered with the IDM. In addition an application corresponding to the proxy must be created in the IDM.
  • The PEP proxy intercepts the incoming service call. This involves 2 steps:
    • The OAuth2 token in the incoming call is verified with the IDM.
    • The user’s roles, the action, the resource and the application ID are forwarded to the Authorization PDP server that compares the request with the set of access policies stored in the server.

architecture

Interactions

PEP Proxy Authentication

The PEP proxy needs to retrieve an access token from the IDM in order to be able to validate incoming OAuth2 tokens on behalf of clients and retrieve details regarding the associated user roles.

The PEP proxy username and password is retrieved from the top-level config.js file.

POST /v3/auth/tokens HTTP/1.1
User-Agent: node-XMLHttpRequest
Accept: */*
Content-Type: application/json
Host: idm:5000
Content-Length: 175
Connection: close

{
  "auth": {
    "identity": {
      "methods": [
        "password"
      ],
      "password": {
        "user": {
          "name": "pepproxy@test.com",
          "password": "test",
          "domain": {
            "id": "default"
          }
        }
      }
    },
    "scope": {
      "domain": {
        "id": "default"
      }
    }
  }
}

The access token is included in the reply in the X-Subject-Token header.

HTTP/1.1 201 Created
X-Subject-Token: 91ca078990524002ba7777fa0bf4408b
Vary: X-Auth-Token
Content-Type: application/json
Content-Length: 959
Date: Mon, 07 Mar 2016 21:02:37 GMT
Connection: close

{
  "token": {
    "domain": {
      "id": "default",
      "name": "Default"
    },
    "methods": [
      "password"
    ],
    "roles": [
      {
        "id": "be19ae44014349c4a9dd614bb413ab64",
        "name": "member"
      }
    ],
    "expires_at": "2016-03-07T22:02:37.646619Z",
    "catalog": [
      {
        "endpoints": [
          {
            "region_id": "Spain2",
            "url": "http://127.0.0.1:35357/v3/",
            "region": "Spain2",
            "interface": "internal",
            "id": "39aec7cd210f439c974b0dce52983d50"
          },
          {
            "region_id": "Spain2",
            "url": "http://127.0.0.1:35357/v3/",
            "region": "Spain2",
            "interface": "admin",
            "id": "78db8f42965e43c8b54ae587ef067d9a"
          },
          {
            "region_id": "Spain2",
            "url": "http://127.0.0.1:5000/v3/",
            "region": "Spain2",
            "interface": "public",
            "id": "835b7fd1e3f34f9aa88db817b7ab5f03"
          }
        ],
        "type": "identity",
        "id": "6ffd78687e984bfe8da5eb8f812296ca",
        "name": "keystone"
      }
    ],
    "extras": {},
    "user": {
      "domain": {
        "id": "default",
        "name": "Default"
      },
      "id": "pepproxy",
      "name": "pepproxy@test.com"
    },
    "audit_ids": [
      "_jj9BFuoRSC2CrKcpib0Jg"
    ],
    "issued_at": "2016-03-07T21:02:37.646646Z"
  }
}

Client Authentication

Client requests to the protected service are intercepted by the PEP proxy. The proxy validates the associated OAuth2 token with the IDM. The token is pulled from the X-Auth-Token header or the standard OAuth2 Authorization: Bearer {token} header.

The client retrieves an OAuth2 token directly from the IDM service using the confidential direct-grant flow:

POST /oauth2/token HTTP/1.1
User-Agent: curl/7.38.0
Host: idm
Accept: */*
Authorization: Basic MDczNzUzZmNmNDBmNDVmNzhhMDIwZDYxNDBiNzY5YjQ6NzMzNDc3N2I1MDgzNDk0MGEzZmM3OTA5Yjc2Y2EyYTQ=
Content-Type: application/x-www-form-urlencoded
Content-Length: 147

grant_type=password&username=user0@test.com&password=test&client_id=073753fcf40f45f78a020d6140b769b4&client_secret=7334777b50834940a3fc7909b76ca2a4
HTTP/1.1 200 OK
Date: Mon, 07 Mar 2016 21:45:20 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: Accept-Language,Cookie
X-Frame-Options: SAMEORIGIN
Content-Language: en
Transfer-Encoding: chunked
Content-Type: application/json

{
  "access_token": "XCTiZUacuABA37VtxlRmIVDufHkbdJ",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "0CO2ZnmvTqJ77Wj1IrtlzGMeIQ7cPg"
}

Then the client issues a call to the protected service. In this case, the client issues a request to the Orion context broker to create a context with 2 attributes.

POST /v1/updateContext HTTP/1.1
Host: 192.168.99.100:1026
Connection: keep-alive
Content-Length: 517
Accept: application/json
Cache-Control: no-cache
x-auth-token: tQUD24RjIdrKNhG6YBzEzQnrfUMR3x
Content-Type: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Postman-Token: 875cff8c-4a89-9098-d716-138088e0025e
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8

{
    "contextElements": [
        {
            "type": "Room",
            "isPattern": "false",
            "id": "Room1",
            "attributes": [
                {
                    "name": "temperature",
                    "type": "float",
                    "value": "23"
                },
                {
                    "name": "pressure",
                    "type": "integer",
                    "value": "720"
                }
            ]
        }
    ],
    "updateAction": "APPEND"
} 

The PEP proxy validates the incoming token. The URL contains the client token to be validated. The X-Auth-Token header holds the PEP proxy access token.

GET /v3/access-tokens/tQUD24RjIdrKNhG6YBzEzQnrfUMR3x HTTP/1.1
User-Agent: node-XMLHttpRequest
Accept: application/json
X-Auth-Token: 91ca078990524002ba7777fa0bf4408b
Host: idm:5000
Connection: close

In addition to validating the token, the reply includes the user’s roles and the ID of the application that the token has been issued for.

HTTP/1.1 200 OK
Vary: X-Auth-Token
Content-Type: application/json
Content-Length: 216
Date: Mon, 07 Mar 2016 21:34:38 GMT
Connection: close

{
  "organizations": [],
  "displayName": "user0",
  "roles": [
    {
      "name": "Orion Operations",
      "id": "a7cdfe346dd2468085e09c235d2a8311"
    }
  ],
  "app_id": "073753fcf40f45f78a020d6140b769b4",
  "email": "user0@test.com",
  "id": "user0"
}

Client Authorization

The PEP proxy generates an authorization request to AuthZForce using the user’s details retrieved during the token validation and the initial client request that contains the resource and the action.

The resource ID refers to the PEP proxy application ID registered with the IDM. The request path /authzforce/domains/032543f7-da0a-11e5-b595-15ad990bc8c9 is retrieved from the config.js file. The included domain ID refers to the registered domain in AuthZForce.

POST /authzforce/domains/032543f7-da0a-11e5-b595-15ad990bc8c9/pdp HTTP/1.1
User-Agent: node-XMLHttpRequest
Accept: application/xml
X-Auth-Token: tQUD24RjIdrKNhG6YBzEzQnrfUMR3x
Content-Type: application/xml
Host: authzforce:8080
Content-Length: 1406
Connection: close

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Request xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" CombinedDecision="false" ReturnPolicyIdList="false">
  <Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
    <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" IncludeInResult="false">
      <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">a7cdfe346dd2468085e09c235d2a8311</AttributeValue>
    </Attribute>
  </Attributes>
  <Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
    <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" IncludeInResult="false">
      <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">073753fcf40f45f78a020d6140b769b4</AttributeValue>
    </Attribute>
    <Attribute AttributeId="urn:thales:xacml:2.0:resource:sub-resource-id" IncludeInResult="false">
      <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">v1/updateContext</AttributeValue>
    </Attribute>
  </Attributes>
  <Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
    <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" IncludeInResult="false">
      <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">POST</AttributeValue>
    </Attribute>
  </Attributes>
  <Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"></Attributes>
</Request>
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Date: Mon, 07 Mar 2016 21:34:38 GMT
Content-Type: application/xml
Content-Length: 316
Connection: close

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:ns2="http://thalesgroup.com/authzforce/pdp/model/2014/12">
  <Result>
    <Decision>Permit</Decision>
    <Status><StatusCode Value="urn:oasis:names:tc:xacml:1.0:status:ok"/></Status>
  </Result>
</Response>

References

Leave a Reply

Your email address will not be published. Required fields are marked *