{"id":6639,"date":"2013-01-15T15:47:35","date_gmt":"2013-01-15T14:47:35","guid":{"rendered":"http:\/\/blog.trifork.nl\/?p=6639"},"modified":"2013-01-15T15:47:35","modified_gmt":"2013-01-15T14:47:35","slug":"building-a-captive-portal-controlling-access-to-the-internet-from-your-network","status":"publish","type":"post","link":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/","title":{"rendered":"Building a Captive Portal &#8211; controlling access to the internet from your network"},"content":{"rendered":"<p><strong>What is a captive portal?<\/strong><br \/>\nWikipedia says: &#8220;The captive portal technique forces an HTTP client on a network to see a special web page (usually for authentication purposes) before using the Internet normally. A captive portal turns a Web browser into an authentication device. This is done by intercepting all packets, regardless of address or port, until the user opens a browser and tries to access the Internet.&#8221;<\/p>\n<p>Basically, when accessing a network (in most cases a WIFI network), a captive portal will block any traffic (to for instance the internet) as long as the client did not go through a predefined workflow. That workflow begins when the user opens a web browser, and via that same browser the client is required to for instance:<\/p>\n<ul>\n<li>authenticate itself<\/li>\n<li>accept terms<\/li>\n<li>pay fees<\/li>\n<li>etc.<\/li>\n<\/ul>\n<p>In this post, I will show you how you can build this kind of solution for your own network using several open source tools, primarily <a title=\"CoovaChilli\" href=\"http:\/\/www.coova.org\/CoovaChilli\" target=\"_blank\" rel=\"noopener\">CoovaChilli<\/a>.<br \/>\n<!--more--><\/p>\n<h3>Components<\/h3>\n<p>In order to build a Captive Portal solution, you will need several open source components, that need to work together, the diagram below illustrates this:<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg\"><\/p>\n<ul>\n<li>An access controller: <a title=\"CoovaChilli\" href=\"http:\/\/www.coova.org\/CoovaChilli\" target=\"_blank\" rel=\"noopener\">CoovaChilli<\/a> &#8211; is a feature rich software access controller that provides a captive portal \/ walled-garden environment<\/li>\n<li>A radius server for provisioning and accounting: <a title=\"freeradius\" href=\"http:\/\/freeradius.org\/\" target=\"_blank\" rel=\"noopener\">Freeradius<\/a> &#8211; handles authentication and accounting (<code>rlm_jradius<\/code> module is required)<\/li>\n<li>A library to implement the business logic: <a title=\"JRadius\" href=\"http:\/\/www.coova.org\/JRadius\" target=\"_blank\" rel=\"noopener\">JRadius<\/a> &#8211; an open-source Java RADIUS client and server framework, which helps you to implement RADIUS authentication and accounting in your Java application<\/li>\n<li>A database: <a title=\"mysql\" href=\"http:\/\/www.mysql.com\/\" target=\"_blank\" rel=\"noopener\">MySQL<\/a> &#8211; backing the Radius server<\/li>\n<li>A web server: <a title=\"apache httpd\" href=\"http:\/\/httpd.apache.org\/\" target=\"_blank\" rel=\"noopener\">Apache HTTPD<\/a> &#8211; proxies request to tomcat<\/li>\n<li>An application server: <a title=\"Tomcat\" href=\"http:\/\/tomcat.apache.org\/\" target=\"_blank\" rel=\"noopener\">Tomcat<\/a> &#8211; for hosting the Captive Portal application<\/li>\n<\/ul>\n<h3>Interactions<\/h3>\n<p>When a client connects to an open WIFI network, an IP address is assigned (CoovaChilli comes with its owns DHCP server). Then, when the client opens a browser and tries to open a URL (e.g. <code>http:\/\/www.google.com<\/code>) CoovaChilli will intercept that and redirect the client to the Captive Portal application which is hosted on Tomcat (in our case it is a Spring MVC application). In order to restrict all access to the outside world, CoovaChilli will add several <code>iptable<\/code> rules to block all ports (no trafic is possible to any service) except CoovaChilli UAM port (DNS port, &#8230;).<br \/>\nWhen the client logs in via the Captive Portal application, <a title=\"CoovaChilli JSON\" href=\"http:\/\/coova.org\/CoovaChilli\/JSON\" target=\"_blank\" rel=\"noopener\">CoovaChilli JSON<\/a> will request an encrypted password (to an UAM service via HTTPS hosted in Tomcat) by sending an access request to the Freeradius server:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nChilliSpot-Version = 1.2.9\nUser-Name = myuser\nUser-Password = &#x5B;Encrypted String]\nService-Type = Login-User\nAcct-Session-Id = 50ed34fb00000003\nFramed-IP-Address = 172.50.70.173\nNAS-Port-Type = Wireless-802.11\nNAS-Port = 3\nNAS-Port-Id = 00000003\nCalling-Station-Id = 00-16-6F-69-8B-B7\nCalled-Station-Id = 00-0C-29-19-D9-D0\nNAS-IP-Address = 172.50.70.1\nNAS-Identifier = nas01\nWISPr-Location-ID = isocc=,cc=,ac=,network=\nWISPr-Location-Name = MY_WLAN\nWISPr-Logoff-URL = http:\/\/172.50.70.1:3990\/logoff\nMessage-Authenticator = &#x5B;Binary Data (length=16)]\n<\/pre>\n<p>When Freeradius receives the message, it will look in its configuration to determinate which module should handle it. In our case, we have set up JRadius to handle these requests, so Freeradius will forward the request to JRadius. In our case, we have configured our own Java classes in JRadius that talk to an external system to perform the authentication. But obviously, this could be any kind of authentication using whatever mechanism (e.g. LDAP and database). If the authentication is successful, an <code>access accept<\/code> response is sent back to CoovaChilli. If not, an <code>access reject<\/code> response is sent back. The response contains a reply message that will be passed on via CoovaChilli to the Captive Portal application. Freeradius will ensure that the result of this transaction is saved to an authentication log.<\/p>\n<h3>Configuration<\/h3>\n<p>This section will describe and list some of the specific configuration you need to do in order to build this setup.<\/p>\n<h4>CoovaChilli<\/h4>\n<p>CoovaChilli needs two network interface, we choose eth0 and eth1.<\/p>\n<ul>\n<li><em>eth0<\/em>: The WAN interface that connect to the internet<\/li>\n<li><em>eth1<\/em>: The LAN interface to which client connect<\/li>\n<\/ul>\n<p>When started, CoovaChilli will create a new virtual interface <em>tun0<\/em>, a tunnel interface to <em>eth1<\/em>. Furthermore, CoovaChilli needs some extra settings: the hotspot IP address, the UAM port (default is 3990), the DNS server(s) and the Freeradius server (IP address, port, secret).<br \/>\nNext to the settings above, the one of interest to us next is the location of the Captive Portal page, CoovaChilli expects the <code>uamserver<\/code> setting to be set to the URL of that page. In our case it is the URL of the login application (e.g. <code>http:\/\/hotspot.trifork.nl\/logon<\/code>).<br \/>\nNote that we use HTTP and not HTTPS, the clear password is sent by CoovaChilli JSON to the UAM service via HTTPS (e.g. <code>https:\/\/hotspot.trifork.nl\/uam.js<\/code>), while the service returns an encryted password (using the challenge passed by CoovaChilli).<\/p>\n<h4>Freeradius<\/h4>\n<p>Freeradius has quite a few configuration settings, I will just mention the JRadius bit, as the rest can be easily understood. The <code>rlm_jradius<\/code> configuration is needed this can be added directly in <code>radiusd.conf<\/code>:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\njradius {\nname      = &quot;trifork&quot;\nprimary   = &quot;localhost&quot;\ntimeout   = 1\nonfail    = NOOP\nkeepalive = yes\nconnections = 8\nallow_codechange = yes\n}\n<\/pre>\n<p>Basically this configuration says that JRadius runs locally and on the default port.<\/p>\n<p>The connection between a request type and the module that will handle it can be added in the default server (<code>\/etc\/raddb\/sites-enabled\/default<\/code>):<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nauthorize {\npreprocess\njradius {\nfail = return\n}\nsuffix\nfiles\ndaily\n}\n\nauthenticate {\njradius\n}\n<\/pre>\n<p>Each module you specify in a section will handle the request. The request is handled in the order in which the modules are listed. What is important is the presence of the <code>jradius<\/code> module we need in order to get our business logic to be triggered. of course there are a lot of other settings, but those are out-of-scope for this blog entry.<\/p>\n<h4>JRadius<\/h4>\n<p>JRadius is a daemon written in Java, which listens to requests on a port (default 1814). The <code>rlm_jradius<\/code> freeradius module sends these requests and takes care of the responses. Extract the JRadius archive somewhere and open the <code>jradius-config.xml<\/code> config file. We need to add some configuration in order for our classes to be triggered when a given request type comes in. We first add a packet-handler under the packet-handlers node:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&amp;lt;packet-handler name=&quot;MyAuth&quot;&amp;gt;\n&amp;lt;description&amp;gt;Custom authorization&amp;lt;\/description&amp;gt;\n&amp;lt;class&amp;gt;nl.trifork.jradius.handler.MyAuthorizationHandler&amp;lt;\/class&amp;gt;\n&amp;lt;\/packet-handler&amp;gt;\n<\/pre>\n<p>And we add this handler in the existing <code>FreeRadiusListener<\/code>:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&amp;lt;packet-handler type=&quot;authorize&quot; handler=&quot;MyAuth&quot;\/&amp;gt;\n<\/pre>\n<p>This means that authorization requests (packets) will be processed by our packet handler. The handler is a Java class extending <code>net.jradius.handler.PacketHandlerBase<\/code>. You need to override the <code>handle()<\/code> method and set the reply packet of the <code>JRadiusRequest<\/code> to <code>AccessAccept<\/code> or <code>AccessReject<\/code>. Make sure to package this class in a JAR file and put it in the lib directory of JRadius.<\/p>\n<h4>Tomcat<\/h4>\n<p>Last, you need a web application that will display the login page and send the authentication to CoovaChilli. You can start with a simple HTML form that will actually not be posted to the backend because everything will happen in Javascript thanks to CoovaChilli JSON. You need to include the <a title=\"ChilliLibrary.js\" href=\"http:\/\/dev.coova.org\/svn\/coova-chilli\/www\/ChilliLibrary.js\" target=\"_blank\" rel=\"noopener\">ChilliLibrary.js<\/a> in the HEAD section of your form page. That Javascript file will give you access to a Javascript object: <code>chilliController<\/code><\/p>\n<p>It needs to be initialized:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nchilliController.host = &quot;172.50.70.1&quot;;\nchilliController.port = &quot;3990&quot;;\nchilliController.uamService = &quot;https:\/\/hotspot.trifork.nl\/uam.js&quot;;\nchilliController.onUpdate = updateUI;\n<\/pre>\n<p>When clicking the login button, we call a javascript function:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction connect() {\nvar username =  document.getElementById('username').value ;\nvar password =  document.getElementById('password').value ;\n\nif (username == null || username == '') {\nshowError();\n}\n\nshowWaitPage(1000);\nchilliController.logon( username , password ) ;\n}\n<\/pre>\n<p>This function just calls the login method of the <code>chilliController<\/code>, that will first use <code>uamService<\/code> to get an encrypted password and then send the credentials to CoovaChilli.<\/p>\n<p>You also need to define an <code>updateUI<\/code> function that will be called after logon is done.<br \/>\nThat function will check the value of <code>chilliController.clientState<\/code> and display an error message or a success message.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction updateUI (cmd ) {\nif ( chilliController.clientState == 0 ) {\nshowErrorPage();\n}\nif ( chilliController.clientState == 1 ) {\nshowSuccessPage();\n}\n}\n<\/pre>\n<p>You can add a logout button that calls the function below in order to log off the user.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction disconnect() {\nif (confirm('Really?')) {\nchilliController.logoff();\n}\nreturn false;\n}\n<\/pre>\n<h3>Conclusion<\/h3>\n<p>It can become quite a challenge when integrating with other systems. I didn&#8217;t mention accounting but you can also integrate accounting via JRadius, for example if you need to update a user balance on an external system (time spend, data downloaded,&#8230;).&nbsp;You can also setup a secure connection between the client and the access point (WPA) allow to be logged in as guest and then still present the user with the captive portal login page. All in all hope this helps you build the Captive Portal you need.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What is a captive portal? Wikipedia says: &#8220;The captive portal technique forces an HTTP client on a network to see a special web page (usually for authentication purposes) before using the Internet normally. A captive portal turns a Web browser into an authentication device. This is done by intercepting all packets, regardless of address or [&hellip;]<\/p>\n","protected":false},"author":83,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[10,124],"tags":[322,323,324,325],"class_list":["post-6639","post","type-post","status-publish","format-standard","hentry","category-development","category-system-administration","tag-captive-portal","tag-coovachilli","tag-radius","tag-wifi"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building a Captive Portal - controlling access to the internet from your network - Trifork Blog<\/title>\n<meta name=\"description\" content=\"Discover how you can build a Captive Portal solution for your own network using several open source tools, primarily CoovaChilli\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a Captive Portal - controlling access to the internet from your network - Trifork Blog\" \/>\n<meta property=\"og:description\" content=\"Discover how you can build a Captive Portal solution for your own network using several open source tools, primarily CoovaChilli\" \/>\n<meta property=\"og:url\" content=\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/\" \/>\n<meta property=\"og:site_name\" content=\"Trifork Blog\" \/>\n<meta property=\"article:published_time\" content=\"2013-01-15T14:47:35+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg\" \/>\n<meta name=\"author\" content=\"Mohamed El Moussaoui\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mohamed El Moussaoui\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/\",\"url\":\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/\",\"name\":\"Building a Captive Portal - controlling access to the internet from your network - Trifork Blog\",\"isPartOf\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg\",\"datePublished\":\"2013-01-15T14:47:35+00:00\",\"author\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/e83488f033bd62395bd3eb801ddf8972\"},\"description\":\"Discover how you can build a Captive Portal solution for your own network using several open source tools, primarily CoovaChilli\",\"breadcrumb\":{\"@id\":\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#primaryimage\",\"url\":\"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg\",\"contentUrl\":\"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/trifork.nl\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a Captive Portal &#8211; controlling access to the internet from your network\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/trifork.nl\/blog\/#website\",\"url\":\"https:\/\/trifork.nl\/blog\/\",\"name\":\"Trifork Blog\",\"description\":\"Keep updated on the technical solutions Trifork is working on!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/trifork.nl\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/e83488f033bd62395bd3eb801ddf8972\",\"name\":\"Mohamed El Moussaoui\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d239ca3a713280c0c1b58648c249fd57?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d239ca3a713280c0c1b58648c249fd57?s=96&d=mm&r=g\",\"caption\":\"Mohamed El Moussaoui\"},\"url\":\"https:\/\/trifork.nl\/blog\/author\/mohamedm\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building a Captive Portal - controlling access to the internet from your network - Trifork Blog","description":"Discover how you can build a Captive Portal solution for your own network using several open source tools, primarily CoovaChilli","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/","og_locale":"en_US","og_type":"article","og_title":"Building a Captive Portal - controlling access to the internet from your network - Trifork Blog","og_description":"Discover how you can build a Captive Portal solution for your own network using several open source tools, primarily CoovaChilli","og_url":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/","og_site_name":"Trifork Blog","article_published_time":"2013-01-15T14:47:35+00:00","og_image":[{"url":"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg","type":"","width":"","height":""}],"author":"Mohamed El Moussaoui","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Mohamed El Moussaoui","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/","url":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/","name":"Building a Captive Portal - controlling access to the internet from your network - Trifork Blog","isPartOf":{"@id":"https:\/\/trifork.nl\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#primaryimage"},"image":{"@id":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#primaryimage"},"thumbnailUrl":"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg","datePublished":"2013-01-15T14:47:35+00:00","author":{"@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/e83488f033bd62395bd3eb801ddf8972"},"description":"Discover how you can build a Captive Portal solution for your own network using several open source tools, primarily CoovaChilli","breadcrumb":{"@id":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#primaryimage","url":"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg","contentUrl":"http:\/\/coova.org\/sites\/coova.org\/files\/images\/Chilli_2.preview.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/trifork.nl\/blog\/building-a-captive-portal-controlling-access-to-the-internet-from-your-network\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/trifork.nl\/blog\/"},{"@type":"ListItem","position":2,"name":"Building a Captive Portal &#8211; controlling access to the internet from your network"}]},{"@type":"WebSite","@id":"https:\/\/trifork.nl\/blog\/#website","url":"https:\/\/trifork.nl\/blog\/","name":"Trifork Blog","description":"Keep updated on the technical solutions Trifork is working on!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/trifork.nl\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/e83488f033bd62395bd3eb801ddf8972","name":"Mohamed El Moussaoui","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d239ca3a713280c0c1b58648c249fd57?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d239ca3a713280c0c1b58648c249fd57?s=96&d=mm&r=g","caption":"Mohamed El Moussaoui"},"url":"https:\/\/trifork.nl\/blog\/author\/mohamedm\/"}]}},"_links":{"self":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/6639","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/users\/83"}],"replies":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/comments?post=6639"}],"version-history":[{"count":0,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/6639\/revisions"}],"wp:attachment":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media?parent=6639"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/categories?post=6639"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/tags?post=6639"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}