DeviceID with APM and API Server
This article covers the use case to use APM and an external API Server to store DeviceID+.
As you learnt in the previous articles in this series, DeviceID+ is a way to "identify" a user. And of course, it is a great solution to combine with F5 APM (Access Policy Manager) - https://www.f5.com/products/security/access-policy-manager
The F5 Shape DeviceID+ solution does not store the IDs anywhere. It is up to you to store/use/consume them on your own. To do so, I propose to use an external API Server to store the DeviceID / Username peer.
Steps:
- Built an API server based on loopback.io stack.
- You can download the project (docker-compose) here : https://github.com/MattDierick/DeviceID-api-server/blob/main/README.md
- Build an APM Pre Request Policy with HTTP Connector to query the API server (available also on my Github)
- Created the Postman collection (available also on my Github)
First of all, watch the demo video to understand the use case and the outcomes: https://www.youtube.com/watch?v=PVYwh76nGVE
The API Server:
The API server has a Swagger UI installed so you can "watch" the API (go to /explorer)
Structure of the API
Below is the structure of the API payload. As you can see, we store the username with the associated DeviceIDs
{ "username": "dierick", "deviceid": [ "Ac31A2AAAAAA12uwoekcLffhgfjgjghj", "AUq7Xti2Eowm6yVog4CYvt6nRrookqgW" ] }
The REST calls used by APM
1. GET DeviceID per username
GET /api/deviceids/findOne?filter={"where":{"username":"dierick"}}
2. POST a new DeviceID
POST /api/deviceids HTTP/1.1 { "username": "dierick", "deviceid": [ "Ac31A2AAAAAA12uwoekcLffhgfjgjghj", "AUq7Xti2Eowm6yVog4CYvt6nRrookqgW" ] }
3. UPDATE DeviceID per username
POST /api/deviceids/upsertWithWhere?where={"username": "dierick"} HTTP/1.1 { "deviceid": [ "Rtdsflkj534565465kenfter" ] }
The iRule to collect the DeviceID from the Shape cookie
when ACCESS_SESSION_STARTED { log local0. "Access Session Started" if [HTTP::cookie exists _imp_apg_r_] { set deviceid [URI::decode [HTTP::cookie _imp_apg_r_]] log local0. "URL Decoded cookie is $deviceid" set deviceida [lindex [regexp -inline -- (?:"diA":")(.*?)(?:") $deviceid] 1] log local0. "diA = $deviceida" set deviceidb [lindex [regexp -inline -- (?:"diB":")(.*?)(?:") $deviceid] 1] log local0. "diB = $deviceidb" log local0. "IP is [IP::client_addr]" log local0. "Path os [HTTP::path]" ACCESS::session data set session.logon.deviceid $deviceid ACCESS::session data set session.logon.deviceid.A $deviceida ACCESS::session data set session.logon.deviceid.B $deviceidb } else { log local0. "No cookie" } }
The APM Per Request Policy
Below an example using the APM Per Request Policy. A Per Request Policy is required instead of a Per Session Policy in order to use the HTTP Connector.
HTTP Connector is a REST API client. Create the different CALLS, and assign each call in the right branch (new DeviceID, update DeviceID ...)