{"id":326,"date":"2023-01-03T15:44:48","date_gmt":"2023-01-03T13:44:48","guid":{"rendered":"http:\/\/www.descher.at\/descher-vu\/?p=326"},"modified":"2023-01-03T15:44:50","modified_gmt":"2023-01-03T13:44:50","slug":"nginx-basic-authentication-against-keycloak","status":"publish","type":"post","link":"http:\/\/www.descher.at\/descher-vu\/2023\/01\/nginx-basic-authentication-against-keycloak\/","title":{"rendered":"Nginx Basic Authentication against Keycloak"},"content":{"rendered":"\n<p class=\"has-medium-font-size\">Due to some updates in our infrastructure, I was looking for a means to authenticate nginx against a keycloak backend. I found some solutions, using <a href=\"https:\/\/bocharoviliyav.blog\/devops\/2021\/01\/21\/Nginx-custom-auth.html\">Lua<\/a> or commercial <a href=\"https:\/\/docs.nginx.com\/nginx\/deployment-guides\/single-sign-on\/keycloak\/\">plugins<\/a>.<\/p>\n\n\n\n<p class=\"has-medium-font-size\">I thought, that this might be doable with &#8222;pure nginx means&#8220; only, and I think, to some degree, I succeeded.<\/p>\n\n\n\n<p class=\"has-medium-font-size\">Lets just skip the explanation, and show some code, where we want to protect location &#8222;\/&#8220; by basic auth forwarded to keycloak<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code># nginx.conf\nlocation \/ {\n    root \/var\/html;\n    satisfy any;\n    auth_request \/auth_keycloak;\n}\n\nlocation \/auth_keycloak {\n\t\tproxy_pass https:\/\/keycloak.com\/realms    \n                           \/myRealm\/protocol\/openid-connect\n                           \/token;\n\t\tproxy_method POST;\n\t\tproxy_pass_header Authorization;\t\n\t\tproxy_set_header Content-Type \n                           \"application\/x-www-form-urlencoded\";\n\t\tproxy_set_body \"client_id=clientId&amp;\n                           client_secret=clientSecret&amp;\n                           grant_type=password\";\n}<\/code><\/pre>\n\n\n\n<p class=\"has-medium-font-size\">We delegate the authentication in &#8222;\/&#8220; to the location &#8222;\/auth_keycloak&#8220; and as mentioned in the <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_auth_request_module.html\">documentation<\/a>: <em>If the subrequest returns a 2xx response code, the access is allowed. If it returns 401 or 403, the access is denied with the corresponding error code.<\/em><\/p>\n\n\n\n<p class=\"has-medium-font-size\">So we need to fix a client in keycloak, that will answer correctly to the given request. Formally the passed request is a &#8222;direct access grant&#8220; request. But there is a slight change. No username and password are passed, instead these are passed via <em>proxy_pass_header Authorization<\/em>.<\/p>\n\n\n\n<p class=\"has-medium-font-size\">How can this be achieved? The secret is in the supported flows. I assume that you are familiar with keycloak basics, thus I only show the relevant parts:<\/p>\n\n\n\n<p class=\"has-medium-font-size\">I override the <em>Direct Grant Flow <\/em>with a <em>http challenge<\/em> flow, which removes the requirement for the <em>username<\/em> and <em>password<\/em> passing as form value, and reads the Authorization header.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"312\" src=\"http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-1024x312.png\" alt=\"\" class=\"wp-image-328\" srcset=\"http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-1024x312.png 1024w, http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-300x91.png 300w, http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-768x234.png 768w, http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik.png 1153w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"has-medium-font-size\">Also I deactive the other non-required capabilities!<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"409\" src=\"http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-1.png\" alt=\"\" class=\"wp-image-330\" srcset=\"http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-1.png 960w, http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-1-300x128.png 300w, http:\/\/www.descher.at\/descher-vu\/wp-content\/uploads\/2023\/01\/grafik-1-768x327.png 768w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/><\/a><\/figure>\n\n\n\n<p class=\"has-medium-font-size\">Now, at least for me, with this reduced solution, I managed to do Nginx Basic Authentication backed by a keycloak service. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Due to some updates in our infrastructure, I was looking for a means to authenticate nginx against a keycloak backend. I found some solutions, using Lua or commercial plugins. I thought, that this might be doable with &#8222;pure nginx means&#8220; only, and I think, to some degree, I succeeded. Lets just skip the explanation, and &hellip; <a href=\"http:\/\/www.descher.at\/descher-vu\/2023\/01\/nginx-basic-authentication-against-keycloak\/\" class=\"more-link\"><span class=\"screen-reader-text\">Nginx Basic Authentication against Keycloak<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":334,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[26,25],"_links":{"self":[{"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/posts\/326"}],"collection":[{"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/comments?post=326"}],"version-history":[{"count":6,"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/posts\/326\/revisions"}],"predecessor-version":[{"id":336,"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/posts\/326\/revisions\/336"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/media\/334"}],"wp:attachment":[{"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/media?parent=326"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/categories?post=326"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.descher.at\/descher-vu\/wp-json\/wp\/v2\/tags?post=326"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}