allow configurability of JWT claims that require a value

e.g;

[jwt]
required_claims = {iss, "https://example.com/issuer"}
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index 6fe2260..057ed4c 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -142,7 +142,9 @@
 
 ;[jwt_auth]
 ; List of claims to validate
-; required_claims =
+; can be the name of a claim like "exp" or a tuple if the claim requires
+; a parameter
+; required_claims = exp, {iss, "IssuerNameHere"}
 ;
 ; [jwt_keys]
 ; Configure at least one key here if using the JWT auth handler.
diff --git a/src/couch/src/couch_httpd.erl b/src/couch/src/couch_httpd.erl
index ef90d6b..8f7fedd 100644
--- a/src/couch/src/couch_httpd.erl
+++ b/src/couch/src/couch_httpd.erl
@@ -931,6 +931,8 @@
     {400, <<"illegal_database_name">>, Message};
 error_info({missing_stub, Reason}) ->
     {412, <<"missing_stub">>, Reason};
+error_info({misconfigured_server, Reason}) ->
+    {500, <<"misconfigured_server">>, couch_util:to_binary(Reason)};
 error_info({Error, Reason}) ->
     {500, couch_util:to_binary(Error), couch_util:to_binary(Reason)};
 error_info(Error) ->
diff --git a/src/couch/src/couch_httpd_auth.erl b/src/couch/src/couch_httpd_auth.erl
index 2383be7..0d3add0 100644
--- a/src/couch/src/couch_httpd_auth.erl
+++ b/src/couch/src/couch_httpd_auth.erl
@@ -209,13 +209,22 @@
 
 get_configured_claims() ->
     Claims = config:get("jwt_auth", "required_claims", ""),
-    case re:split(Claims, "\s*,\s*", [{return, list}]) of
-        [[]] ->
-            []; %% if required_claims is the empty string.
-        List ->
-            [list_to_existing_atom(C) || C <- List]
+    Re = "((?<key1>[a-z]+)|{(?<key2>[a-z]+)\s*,\s*\"(?<val>[^\"]+)\"})",
+    case re:run(Claims, Re, [global, {capture,  [key1, key2, val], binary}]) of
+        nomatch when Claims /= "" ->
+            couch_log:error("[jwt_auth] required_claims is set to an invalid value.", []),
+            throw({misconfigured_server, <<"JWT is not configured correctly">>});
+        nomatch ->
+            [];
+        {match, Matches} ->
+            lists:map(fun to_claim/1, Matches)
     end.
 
+to_claim([Key, <<>>, <<>>]) ->
+    binary_to_atom(Key, latin1);
+to_claim([<<>>, Key, Value]) ->
+    {binary_to_atom(Key, latin1), Value}.
+
 cookie_authentication_handler(Req) ->
     cookie_authentication_handler(Req, couch_auth_cache).
 
diff --git a/test/elixir/test/jwtauth_test.exs b/test/elixir/test/jwtauth_test.exs
index 2fb89c3..7281ed1 100644
--- a/test/elixir/test/jwtauth_test.exs
+++ b/test/elixir/test/jwtauth_test.exs
@@ -137,4 +137,81 @@
     assert resp.body["userCtx"]["name"] == "adm"
     assert resp.body["info"]["authenticated"] == "default"
   end
+
+  test "jwt auth with required iss claim", _context do
+
+    secret = "zxczxc12zxczxc12"
+
+    server_config = [
+      %{
+        :section => "jwt_auth",
+        :key => "required_claims",
+        :value => "{iss, \"hello\"}"
+      },
+      %{
+        :section => "jwt_keys",
+        :key => "hmac:_default",
+        :value => :base64.encode(secret)
+      },
+      %{
+        :section => "jwt_auth",
+        :key => "allowed_algorithms",
+        :value => "HS256, HS384, HS512"
+      }
+    ]
+
+    run_on_modified_server(server_config, fn -> good_iss("HS256", secret) end)
+    run_on_modified_server(server_config, fn -> bad_iss("HS256", secret) end)
+  end
+
+  def good_iss(alg, key) do
+    {:ok, token} = :jwtf.encode(
+      {
+        [
+          {"alg", alg},
+          {"typ", "JWT"}
+        ]
+      },
+      {
+        [
+          {"iss", "hello"},
+          {"sub", "couch@apache.org"},
+          {"_couchdb.roles", ["testing"]
+          }
+        ]
+      }, key)
+
+    resp = Couch.get("/_session",
+      headers: [authorization: "Bearer #{token}"]
+    )
+
+    assert resp.body["userCtx"]["name"] == "couch@apache.org"
+    assert resp.body["userCtx"]["roles"] == ["testing"]
+    assert resp.body["info"]["authenticated"] == "jwt"
+  end
+
+  def bad_iss(alg, key) do
+    {:ok, token} = :jwtf.encode(
+      {
+        [
+          {"alg", alg},
+          {"typ", "JWT"}
+        ]
+      },
+      {
+        [
+          {"iss", "goodbye"},
+          {"sub", "couch@apache.org"},
+          {"_couchdb.roles", ["testing"]
+          }
+        ]
+      }, key)
+
+    resp = Couch.get("/_session",
+      headers: [authorization: "Bearer #{token}"]
+    )
+
+    assert resp.status_code == 400
+  end
+
 end