{"id":139973,"date":"2021-04-22T02:37:03","date_gmt":"2021-04-22T02:37:03","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/jwt-auth-plugin\/"},"modified":"2025-03-05T04:43:42","modified_gmt":"2025-03-05T04:43:42","slug":"ah-jwt-auth","status":"publish","type":"plugin","link":"https:\/\/pcd.wordpress.org\/plugins\/ah-jwt-auth\/","author":18388444,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.5.4","stable_tag":"1.5.4","tested":"6.7.5","requires":"4.7","requires_php":"7.0","requires_plugins":null,"header_name":"AH JWT Auth","header_author":"Andrew Heberle","header_description":"The plugin authenticates the user and sets role in WordPress via JWT.","assets_banners_color":"","last_updated":"2025-03-05 04:43:42","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/paypal.me\/andrewheberle","header_plugin_uri":"","header_author_uri":"https:\/\/github.com\/andrewheberle\/wordpress-ah-jwt-auth\/","rating":0,"author_block_rating":0,"active_installs":10,"downloads":2482,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","faq","changelog"],"tags":{"1.0.3":{"tag":"1.0.3","author":"andrewheberle","date":"2021-09-24 22:17:43"},"1.1.0":{"tag":"1.1.0","author":"andrewheberle","date":"2021-09-24 22:19:34"},"1.2.0":{"tag":"1.2.0","author":"andrewheberle","date":"2021-09-24 22:19:34"},"1.2.1":{"tag":"1.2.1","author":"andrewheberle","date":"2021-09-24 22:19:34"},"1.2.2":{"tag":"1.2.2","author":"andrewheberle","date":"2021-09-24 22:19:34"},"1.3.0":{"tag":"1.3.0","author":"andrewheberle","date":"2021-10-08 13:17:20"},"1.3.1":{"tag":"1.3.1","author":"andrewheberle","date":"2022-05-18 11:30:06"},"1.4.0":{"tag":"1.4.0","author":"andrewheberle","date":"2022-05-18 13:53:57"},"1.4.1":{"tag":"1.4.1","author":"andrewheberle","date":"2023-08-16 13:27:47"},"1.5.0":{"tag":"1.5.0","author":"andrewheberle","date":"2023-11-09 13:56:23"},"1.5.1":{"tag":"1.5.1","author":"andrewheberle","date":"2023-11-09 14:58:02"},"1.5.2":{"tag":"1.5.2","author":"andrewheberle","date":"2023-12-20 06:41:30"},"1.5.3":{"tag":"1.5.3","author":"andrewheberle","date":"2023-12-21 04:35:03"},"1.5.4":{"tag":"1.5.4","author":"andrewheberle","date":"2025-03-05 04:43:42"}},"upgrade_notice":{"1.0.3":"<p>Initial public release<\/p>","1.0.2":"<p>Internationalisation for strings<\/p>","1.0.1":"<p>Better handling or errors.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":2519495,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":2519495,"resolution":"256x256","location":"assets","locale":""},"icon.svg":{"filename":"icon.svg","revision":2527062,"resolution":false,"location":"assets","locale":false}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.3","1.1.0","1.2.0","1.2.1","1.2.2","1.3.0","1.3.1","1.4.0","1.4.1","1.5.0","1.5.1","1.5.2","1.5.3","1.5.4"],"block_files":[],"assets_screenshots":{"screenshot-1.jpg":{"filename":"screenshot-1.jpg","revision":2519495,"resolution":"1","location":"assets","locale":""}},"screenshots":{"1":"This example shows a configuration with a WordPress install behind Cloudflare Access for SSO via JWT"},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[8382,710,38851,602,2469],"plugin_category":[38],"plugin_contributors":[198722],"plugin_business_model":[],"class_list":["post-139973","plugin","type-plugin","status-publish","hentry","plugin_tags-auth","plugin_tags-authentication","plugin_tags-jwt","plugin_tags-login","plugin_tags-sso","plugin_category-authentication","plugin_contributors-andrewheberle","plugin_committers-andrewheberle"],"banners":[],"icons":{"svg":"https:\/\/ps.w.org\/ah-jwt-auth\/assets\/icon.svg?rev=2527062","icon":"https:\/\/ps.w.org\/ah-jwt-auth\/assets\/icon.svg?rev=2527062","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/ah-jwt-auth\/assets\/screenshot-1.jpg?rev=2519495","caption":"This example shows a configuration with a WordPress install behind Cloudflare Access for SSO via JWT"}],"raw_content":"<!--section=description-->\n<p>This plugin allows sign in to WordPress using a JSON Web Token (JWT) contained in a HTTP Header that is added by a reverse proxy\nthat sits in front of your WordPress deployment.<\/p>\n\n<p>Authentication and optionally role assignment is handled by claims contained in the JWT.<\/p>\n\n<p>Verification of the JWT is handled by either:<\/p>\n\n<ul>\n<li>a shared secret key<\/li>\n<li>retrieving a JSON Web Key Set (JWKS) from a configured URL<\/li>\n<\/ul>\n\n<p>During the login process if the user does not exist an account will be created with a matching role from the JWT.<\/p>\n\n<p>If the JWT did not contain a role claim then user is created with the role set in the plugin settings (by default this is the subscriber role).<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id='what%20header%20is%20the%20jwt%20retrieved%20from%3F'><h3>What header is the JWT retrieved from?<\/h3><\/dt>\n<dd><p>By default the plugin looks for the JWT in the <code>Authorization<\/code> header as follows:<\/p>\n\n<pre><code>Authorization: Bearer &lt;JWT Here&gt;\n<\/code><\/pre>\n\n<p>However the token may be retrieved from a configurable HTTP header, for example integration with Cloudflare Access would use\nthe <code>Cf-Access-Jwt-Assertion<\/code> header.<\/p><\/dd>\n<dt id='what%20should%20the%20jwt%20contain%3F'><h3>What should the JWT contain?<\/h3><\/dt>\n<dd><p>The JWT must contain at least an <code>email<\/code> claim and may also contain a <code>role<\/code> claim:<\/p>\n\n<pre><code>{\n    \"email\": \"admin@example.com\",\n    \"role\": \"admin\"\n}\n<\/code><\/pre><\/dd>\n<dt id='what%20signature%20algorimths%20are%20supported%20to%20verify%20the%20jwt%3F'><h3>What signature algorimths are supported to verify the JWT?<\/h3><\/dt>\n<dd><p>Currently only the HS256 and RS256 alorithms are supported.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.5.4<\/h4>\n\n<ul>\n<li>Fix bug that meant role was not being set based on selection<\/li>\n<\/ul>\n\n<h4>1.5.3<\/h4>\n\n<ul>\n<li>Make JWKS refresh function public<\/li>\n<\/ul>\n\n<h4>1.5.1<\/h4>\n\n<ul>\n<li>Fixes for JWKS refresh process<\/li>\n<\/ul>\n\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>Add WP cron job to refresh JWKS daily<\/li>\n<\/ul>\n\n<h4>1.4.1<\/h4>\n\n<ul>\n<li>Update dependencies to resolve security issue<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Clean-ups and bug fixes<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>Allow setting default role for auto-created users<\/li>\n<\/ul>\n\n<h4>1.2.2<\/h4>\n\n<ul>\n<li>Version bump for plugin update on WordPress.org<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Version bump for plugin update on WordPress.org<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Fix a bug where an invalid JSON response from JWKS URL was cached leading to broken SSO <\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Make login process more efficient by skipping JWT verify\/login if user is already authenticated <\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Initial release on WordPress.org<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Added internationalisation for strings<\/li>\n<li>Changes based on WordPress.org plugin submission feedback<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Added more error checking<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First version<\/li>\n<\/ul>","raw_excerpt":"This plugin allows sign in to WordPress using a JSON Web Token (JWT) contained in a HTTP Header.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/139973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=139973"}],"author":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/andrewheberle"}],"wp:attachment":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=139973"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=139973"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=139973"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=139973"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=139973"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=139973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}