{"id":24603,"date":"2015-08-19T14:04:09","date_gmt":"2015-08-19T12:04:09","guid":{"rendered":"https:\/\/mamchenkov.net\/wordpress\/?p=24603"},"modified":"2016-12-12T11:29:41","modified_gmt":"2016-12-12T09:29:41","slug":"custom-single-sign-on-with-nginx-and-auth-request-module","status":"publish","type":"post","link":"https:\/\/mamchenkov.net\/wordpress\/2015\/08\/19\/custom-single-sign-on-with-nginx-and-auth-request-module\/","title":{"rendered":"Custom Single Sign-On with Nginx and Auth Request Module"},"content":{"rendered":"<!-- google_ad_section_start -->\n<p>In a recent project I crashed into a wall. \u00a0At least for a couple of days that is. \u00a0The requirement was to integrate the <a href=\"https:\/\/bestpractical.com\/docs\/rt\/\">Request Tracker<\/a> (aka RT) installation on <a href=\"https:\/\/www.centos.org\/\">CentOS 7<\/a> server with <a href=\"http:\/\/nginx.org\/\">Nginx<\/a> to\u00a0a client&#8217;s company single sign-on solution. \u00a0Which wasn&#8217;t LDAP. \u00a0Or Active Directory. \u00a0Or anything standard at all &#8211; a complete homegrown system.<\/p>\n<p><!--more--><\/p>\n<p>First set of Google searches firmly suggested to use <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_auth_request_module.html\">ngx_http_auth_request_module<\/a>. \u00a0The instructions seemed quite straightforward. \u00a0However, I was struggling to make it work. \u00a0The reason for that was trivial &#8211; Nginx web server shipped with CentOS 7 is compiled without this module:<\/p>\n<pre class=\"brush: plain; light: true; title: ; notranslate\" title=\"\">\r\n# rpm -qi nginx\r\nName        : nginx\r\nEpoch       : 1\r\nVersion     : 1.6.3\r\nRelease     : 6.el7\r\nArchitecture: x86_64\r\nInstall Date: Wed 05 Aug 2015 06:37:41 AM UTC\r\nGroup       : System Environment\/Daemons\r\nSize        : 1441031\r\nLicense     : BSD\r\nSignature   : RSA\/SHA256, Wed 08 Jul 2015 01:38:40 PM UTC, Key ID 6a2faea2352c64e5\r\nSource RPM  : nginx-1.6.3-6.el7.src.rpm\r\nBuild Date  : Fri 03 Jul 2015 12:44:51 PM UTC\r\nBuild Host  : buildvm-09.phx2.fedoraproject.org\r\nRelocations : (not relocatable)\r\nPackager    : Fedora Project\r\nVendor      : Fedora Project\r\nURL         : http:\/\/nginx.org\/\r\nSummary     : A high performance web server and reverse proxy server\r\nDescription :\r\nNginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and\r\nIMAP protocols, with a strong focus on high concurrency, performance and low\r\nmemory usage.\r\n<\/pre>\n<p>I do know how to build custom RPMs, but that would mean a much increased maintenance, which I wanted to avoid.<\/p>\n<p>So, the next question is: are there any compiled modules that I can use to solve the problem?<\/p>\n<pre class=\"brush: plain; light: true; title: ; notranslate\" title=\"\">\r\n# nginx -V\r\nnginx version: nginx\/1.6.3\r\nbuilt by gcc 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC)\r\nTLS SNI support enabled\r\nconfigure arguments: --prefix=\/usr\/share\/nginx --sbin-path=\/usr\/sbin\/nginx --conf-path=\/etc\/nginx\/nginx.conf --error-log-path=\/var\/log\/nginx\/error.log --http-log-path=\/var\/log\/nginx\/access.log --http-client-body-temp-path=\/var\/lib\/nginx\/tmp\/client_body --http-proxy-temp-path=\/var\/lib\/nginx\/tmp\/proxy --http-fastcgi-temp-path=\/var\/lib\/nginx\/tmp\/fastcgi --http-uwsgi-temp-path=\/var\/lib\/nginx\/tmp\/uwsgi --http-scgi-temp-path=\/var\/lib\/nginx\/tmp\/scgi --pid-path=\/run\/nginx.pid --lock-path=\/run\/lock\/subsys\/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-pcre --with-pcre-jit --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=\/usr\/lib\/rpm\/redhat\/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=\/usr\/lib\/rpm\/redhat\/redhat-hardened-ld -Wl,-E'\r\n<\/pre>\n<p>If you look carefully enough, you&#8217;ll notice the <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_perl_module.html\">ngx_http_perl_module<\/a>. \u00a0Great news! \u00a0If I have Perl, I can do anything. \u00a0A quick scan through the documentation confirms that I should be able to access the request object.<\/p>\n<p>Fast forward a few hours and I still got nowhere. \u00a0The Nginx part was working enough for me to have some test variables and code snippets. \u00a0But in order to work with the request object, I had to have <a href=\"http:\/\/search.cpan.org\/~zzz\/Nginx-Perl-1.2.9.7\/src\/http\/modules\/perl\/Nginx.pm\">Nginx Perl module<\/a> installed on the system. \u00a0Which is not shipped with CentOS 7 as a package. \u00a0And which was failing to compile during the CPAN installation. \u00a0There was something or other about Nginx server not being compiled with sufficient parameters. \u00a0Sorry, I forgot to log the error and I moved on since.<\/p>\n<p>So, is that it? \u00a0No elegant, low maintenance solution then? \u00a0Nginx rebuild required? \u00a0I was very reluctant to believe this. \u00a0And I wasn&#8217;t in a hurry. \u00a0So I stopped and got some sleep. \u00a0And as it often happens, a midnight enlightenment occurred: look for another pre-compiled package for Nginx, don&#8217;t use the one from the CentOS project.<\/p>\n<p>Is there one? \u00a0Yes, of course! \u00a0In fact, there is an official Nginx repository, which supports CentOS (among other distributions), provides a much newer version of Nginx (1.8.0 instead of 1.6.3) and is compiled with the ngx_auth_request_module!<\/p>\n<p>Here is how it looks:<\/p>\n<pre class=\"brush: plain; light: true; title: ; notranslate\" title=\"\">\r\n# rpm -qi nginx\r\nName        : nginx\r\nEpoch       : 1\r\nVersion     : 1.8.0\r\nRelease     : 1.el7.ngx\r\nArchitecture: x86_64\r\nInstall Date: Thu 09 Jul 2015 02:07:42 PM EEST\r\nGroup       : System Environment\/Daemons\r\nSize        : 910765\r\nLicense     : 2-clause BSD-like license\r\nSignature   : RSA\/SHA1, Tue 21 Apr 2015 07:44:08 PM EEST, Key ID abf5bd827bd9bf62\r\nSource RPM  : nginx-1.8.0-1.el7.ngx.src.rpm\r\nBuild Date  : Tue 21 Apr 2015 06:37:00 PM EEST\r\nBuild Host  : centos7-amd64-ovl\r\nRelocations : (not relocatable)\r\nVendor      : nginx inc.\r\nURL         : http:\/\/nginx.org\/\r\nSummary     : High performance web server\r\nDescription :\r\nnginx &#x5B;engine x] is an HTTP and reverse proxy server, as well as\r\na mail proxy server.\r\n\r\n# nginx -V\r\nnginx version: nginx\/1.8.0\r\nbuilt by gcc 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC) \r\nbuilt with OpenSSL 1.0.1e-fips 11 Feb 2013\r\nTLS SNI support enabled\r\nconfigure arguments: --prefix=\/etc\/nginx --sbin-path=\/usr\/sbin\/nginx --conf-path=\/etc\/nginx\/nginx.conf --error-log-path=\/var\/log\/nginx\/error.log --http-log-path=\/var\/log\/nginx\/access.log --pid-path=\/var\/run\/nginx.pid --lock-path=\/var\/run\/nginx.lock --http-client-body-temp-path=\/var\/cache\/nginx\/client_temp --http-proxy-temp-path=\/var\/cache\/nginx\/proxy_temp --http-fastcgi-temp-path=\/var\/cache\/nginx\/fastcgi_temp --http-uwsgi-temp-path=\/var\/cache\/nginx\/uwsgi_temp --http-scgi-temp-path=\/var\/cache\/nginx\/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'\r\n<\/pre>\n<p>Excellent! \u00a0So, now on to the configuration &#8230; what do we need to do there?<\/p>\n<p>First of all, RT configuration is a straightforward FastCGI setup, as per <a href=\"https:\/\/www.bestpractical.com\/docs\/rt\/4.2\/web_deployment.html#nginx\">the documentation<\/a>. \u00a0Adding auth request handling and we have the following location block:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nlocation \/ {\r\n  auth_request \/auth;\r\n  auth_request_set $username $upstream_http_x_username;\r\n\r\n  fastcgi_param  REMOTE_USER        $username;\r\n\r\n  fastcgi_param  QUERY_STRING       $query_string;\r\n  fastcgi_param  REQUEST_METHOD     $request_method;\r\n  fastcgi_param  CONTENT_TYPE       $content_type;\r\n  fastcgi_param  CONTENT_LENGTH     $content_length;\r\n\r\n  fastcgi_param  SCRIPT_NAME        '';\r\n  fastcgi_param  PATH_INFO          $uri;\r\n  fastcgi_param  REQUEST_URI        $request_uri;\r\n  fastcgi_param  DOCUMENT_URI       $document_uri;\r\n  fastcgi_param  DOCUMENT_ROOT      $document_root;\r\n  fastcgi_param  SERVER_PROTOCOL    $server_protocol;\r\n\r\n  fastcgi_param  GATEWAY_INTERFACE  CGI\/1.1;\r\n  fastcgi_param  SERVER_SOFTWARE    nginx\/$nginx_version;\r\n\r\n  fastcgi_param  REMOTE_ADDR        $remote_addr;\r\n  fastcgi_param  REMOTE_PORT        $remote_port;\r\n  fastcgi_param  SERVER_ADDR        $server_addr;\r\n  fastcgi_param  SERVER_PORT        $server_port;\r\n  fastcgi_param  SERVER_NAME        $server_name;\r\n\r\n  fastcgi_pass 127.0.0.1:9000;\r\n}\r\n<\/pre>\n<p>So, what&#8217;s happening here?<\/p>\n<ul>\n<li>Line 1 tells Nginx to authenticate every request using \/auth sub-request. \u00a0That will be a very simple GET request without the body &#8211; just the headers, expecting a 200 OK response status back for anything that authenticated successfully, and any other response status for an authentication failure.<\/li>\n<li>Line 2 tells Nginx to set $username variable to the value of the X-Username response header, coming from the auth sub-request. \u00a0This is handy for those cases where you don&#8217;t only need to know if the user is successfully authenticated, but also who he or she is.<\/li>\n<li>Line 5 sets the REMOTE_USER to the returned $username value, so that the RT can pick it up.<\/li>\n<li>Line 28 tells Nginx where the FastCGI handler is.<\/li>\n<\/ul>\n<p>Now, in the same server block we need to define the handling of the \/auth location. \u00a0Here your mileage may vary, so use the below as a starting point:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nlocation = \/auth {\r\n    proxy_pass http:\/\/localhost:8080;   \r\n    proxy_pass_request_body off;\r\n    proxy_set_header Host $host;\r\n    proxy_set_header X-Real-IP $remote_addr;\r\n    proxy_set_header X-Origin-URI $request_uri;\r\n    proxy_set_header Content-Length '0';\r\n}\r\n<\/pre>\n<p>Whether or not you have everything on the same host is irrelevant. I&#8217;m just keeping this example here for the next time where it won&#8217;t be. The important bits here are about the conversion of POST requests to GET requests. All your \/auth requests will be GET, irrelevant of the original request. So dropping the body of the request and setting Content-Length to 0 sounds like a good idea. \u00a0In fact, in my original configuration I didn&#8217;t have the reset of the Content-Length, which resulted in me pulling out hair for a few hours, trying to understand why requests from 127.0.0.1 to 127.0.0.1 timeout when executed by Nginx (hint: sub-request) and succeed when executed by me from the command line (hint: direct request).<\/p>\n<p>Now, for my authentication mechanism I setup the simplest of PHP virtual hosts, sending all requests to a simple script. \u00a0Here&#8217;s the shortest version purely for illustration:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php \r\nfunction getUsername() { \r\n  \/\/ ... custom authentication \r\n} \r\n$username = getUsername(); \r\nif ($username) { \r\n  header('X-Username: ' . $username, true, 200); \r\n} \r\nelse {\r\n  header('X-Username: ', true, 403); \r\n} \r\n?&gt;\r\n<\/pre>\n<p>We are almost done now. The last thing to do is to send non-authenticated users to the login page. To do so, in our RT&#8217;s virtual host configuration we add the error page handler like so:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nerror_page 403 = @login;\r\nlocation @login {\r\n  rewrite ^.* https:\/\/secure.example.com\/login;\r\n}\r\n<\/pre>\n<p>Don&#8217;t forget to start the Nginx server, FastCGI handler, and PHP FPM, if you opted for the local PHP solution like I did. Cross your fingers and try it out.<\/p>\n<p>Obviously, your application should support external authentication via the REMOTE_USER. For the Request Tracker, you need to set the following your <em>etc\/RT_SiteConfig.pm<\/em>:<\/p>\n<pre class=\"brush: perl; light: true; title: ; notranslate\" title=\"\">\r\nSet($WebRemoteUserAuth, 1);\r\nSet($WebRemoteUserContinuous, 1);\r\nSet($WebFallbackToRTLogin, undef);\r\nSet($WebRemoteUserGecos, 1);\r\nSet($WebRemoteUserAutocreate, 1);\r\n<\/pre>\n<p>Overall, it took me a while to arrive at this configuration, and it might seem slightly complicated at first, but the more I look at it, the more I like. I think it&#8217;s elegant, flexible, and quite low maintenance. Authentication mechanism is external and not web server dependent. The script itself can be adjusted, as the company moves to more standardized solution. The Nginx package is pre-compiled and from a well trusted source. And even the login redirect is handled without any hacking around.<\/p>\n<p>If you have any improvement suggestions, please feel free to let me know via comments.<\/p>\n<!-- google_ad_section_end -->\n","protected":false},"excerpt":{"rendered":"<!-- google_ad_section_start -->\n<p>In a recent project I crashed into a wall. \u00a0At least for a couple of days that is. \u00a0The requirement was to integrate the Request Tracker (aka RT) installation on CentOS 7 server with Nginx to\u00a0a client&#8217;s company single sign-on solution. \u00a0Which wasn&#8217;t LDAP. \u00a0Or Active Directory. \u00a0Or anything standard at all &#8211; a complete &hellip; <a href=\"https:\/\/mamchenkov.net\/wordpress\/2015\/08\/19\/custom-single-sign-on-with-nginx-and-auth-request-module\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Custom Single Sign-On with Nginx and Auth Request Module<\/span><\/a><\/p>\n<!-- google_ad_section_end -->\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Custom Single Sign-On with Nginx and Auth Request Module #nginx #sysadmin #rt #security #sysadmin","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_links_to":"","_links_to_target":""},"categories":[1,6,133,62,1334],"tags":[3164,3150,200,3474],"keyring_services":[],"class_list":["post-24603","post","type-post","status-publish","format-standard","hentry","category-general","category-linux","category-sysadmin","category-technology","category-web-work","tag-nginx","tag-request-tracker","tag-security","tag-single-sign-on"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":24326,"url":"https:\/\/mamchenkov.net\/wordpress\/2015\/06\/09\/sso-with-nginx-auth_request-module\/","url_meta":{"origin":24603,"position":0},"title":"SSO with Nginx auth_request module","author":"Leonid Mamchenkov","date":"June 9, 2015","format":"link","excerpt":"SSO with Nginx auth_request module - SSO as in Single Sign-On. \u00a0Absolutely beautiful solution for one set of requirements, and a horrendous for another. \u00a0Worth knowing though.","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":28234,"url":"https:\/\/mamchenkov.net\/wordpress\/2017\/11\/21\/nginx-module-vts-nginx-virtual-host-traffic-status-module\/","url_meta":{"origin":24603,"position":1},"title":"nginx-module-vts &#8211; Nginx virtual host traffic status module","author":"Leonid Mamchenkov","date":"November 21, 2017","format":false,"excerpt":"nginx-module-vts is a handy Nginx module for those who run complex Nginx configurations, with multiple servers, virtual hosts, caches, etc.\u00a0 Here's an example partial screenshot of the output.","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2017\/11\/nginx-500x441.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":26306,"url":"https:\/\/mamchenkov.net\/wordpress\/2016\/08\/04\/504-gateway-timeout-error-on-nginx-fastcgi-php-fpm\/","url_meta":{"origin":24603,"position":2},"title":"504 Gateway Timeout error on Nginx + FastCGI (php-fpm)","author":"Leonid Mamchenkov","date":"August 4, 2016","format":false,"excerpt":"\"504 Gateway Timeout\" error is a very common issue when using Nginx with PHP-FPM. \u00a0Usually, that means that it took PHP-FPM longer to generate the response, than Nginx was willing to wait for. \u00a0A few possible reasons for this are: Nginx timeout configuration uses very small values (expecting the responses\u2026","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"504","src":"https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2016\/08\/504-500x385.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":27972,"url":"https:\/\/mamchenkov.net\/wordpress\/2017\/09\/08\/nginx-unit\/","url_meta":{"origin":24603,"position":3},"title":"Nginx Unit","author":"Leonid Mamchenkov","date":"September 8, 2017","format":false,"excerpt":"\u00a0 Nginx Unit looks interesting: What is NGINX Unit? NGINX Unit is a new, lightweight, open source application server built to meet the demands of today\u2019s dynamic and distributed applications. Deploy configuration changes with no service disruptions. Run code in multiple languages. Build the foundation of your service mesh. An\u2026","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2017\/09\/nginx-unit-500x336.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":34255,"url":"https:\/\/mamchenkov.net\/wordpress\/2019\/02\/15\/nginx-quick-reference\/","url_meta":{"origin":24603,"position":4},"title":"Nginx Quick Reference","author":"Leonid Mamchenkov","date":"February 15, 2019","format":false,"excerpt":"Nginx Quick Reference is an excellent summary of notes on tweaking the performance and security of the Nginx web server configuration.","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2019\/02\/nginx-hardening-checklist.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2019\/02\/nginx-hardening-checklist.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2019\/02\/nginx-hardening-checklist.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2019\/02\/nginx-hardening-checklist.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2019\/02\/nginx-hardening-checklist.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/mamchenkov.net\/wordpress\/wp-content\/uploads\/2019\/02\/nginx-hardening-checklist.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":21405,"url":"https:\/\/mamchenkov.net\/wordpress\/2014\/03\/27\/ngxtop-real-time-metrics-for-nginx-server\/","url_meta":{"origin":24603,"position":5},"title":"ngxtop &#8211; real-time metrics for nginx server","author":"Leonid Mamchenkov","date":"March 27, 2014","format":"link","excerpt":"ngxtop - real-time metrics for nginx server","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/mamchenkov.net\/wordpress\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/posts\/24603","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/comments?post=24603"}],"version-history":[{"count":0,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/posts\/24603\/revisions"}],"wp:attachment":[{"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/media?parent=24603"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/categories?post=24603"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/tags?post=24603"},{"taxonomy":"keyring_services","embeddable":true,"href":"https:\/\/mamchenkov.net\/wordpress\/wp-json\/wp\/v2\/keyring_services?post=24603"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}