Skip to content

Commit 7fad989

Browse files
authored
feat(support-x-interservice-auth-header): Add support for x-interservice-auth header (#38)
1 parent 8a83da9 commit 7fad989

File tree

7 files changed

+66
-26
lines changed

7 files changed

+66
-26
lines changed

neurow/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,5 @@ neurow-*.tar
2424

2525
# Temporary files, for example, from tests.
2626
/tmp/
27+
28+
*.iml

neurow/lib/neurow/internal_api/endpoint.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ defmodule Neurow.InternalApi.Endpoint do
99
plug(MetricsPlugExporter)
1010

1111
plug(Neurow.JwtAuthPlug,
12+
credential_headers: ["x-interservice-authorization", "authorization"],
1213
jwk_provider: &Neurow.Configuration.internal_api_issuer_jwks/1,
1314
audience: &Neurow.Configuration.internal_api_audience/0,
1415
verbose_authentication_errors:

neurow/lib/neurow/jwt_auth_plug.ex

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ defmodule Neurow.JwtAuthPlug do
55

66
defmodule Options do
77
defstruct [
8+
:credential_headers,
89
:jwk_provider,
910
:audience,
1011
:max_lifetime,
@@ -48,7 +49,7 @@ defmodule Neurow.JwtAuthPlug do
4849
case requires_jwt_authentication?(conn, options) do
4950
true ->
5051
with(
51-
{:ok, jwt_token_str} <- jwt_token_from_request(conn),
52+
{:ok, jwt_token_str} <- jwt_token_from_request(conn, options),
5253
{:ok, _protected, payload} <- parse_jwt_token(jwt_token_str),
5354
{:ok, jwks} <- fetch_jwks_from_issuer(payload, options),
5455
{:ok} <- check_signature(jwt_token_str, jwks, options),
@@ -124,13 +125,16 @@ defmodule Neurow.JwtAuthPlug do
124125
end)
125126
end
126127

127-
defp jwt_token_from_request(conn) do
128-
case conn |> get_req_header("authorization") do
129-
["Bearer " <> jwt_token] ->
130-
{:ok, jwt_token}
131-
132-
_ ->
133-
{:error, :invalid_authorization_header, "Invalid authorization header"}
128+
defp jwt_token_from_request(conn, options) do
129+
Enum.find_value(options.credential_headers, fn header ->
130+
case get_req_header(conn, header) do
131+
["Bearer " <> jwt_token] -> jwt_token
132+
_ -> nil
133+
end
134+
end)
135+
|> case do
136+
nil -> {:error, :invalid_authorization_header, "Invalid authorization header"}
137+
jwt_token -> {:ok, jwt_token}
134138
end
135139
end
136140

@@ -211,7 +215,7 @@ defmodule Neurow.JwtAuthPlug do
211215

212216
defp forbidden(conn, error_code, error_message, options) do
213217
jwt_token =
214-
case conn |> jwt_token_from_request() do
218+
case conn |> jwt_token_from_request(options) do
215219
{:ok, jwt_token} -> jwt_token
216220
_ -> nil
217221
end

neurow/lib/neurow/public_api/endpoint.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ defmodule Neurow.PublicApi.Endpoint do
55
plug(:preflight_request)
66

77
plug(Neurow.JwtAuthPlug,
8+
credential_headers: ["authorization"],
89
jwk_provider: &Neurow.Configuration.public_api_issuer_jwks/1,
910
audience: &Neurow.Configuration.public_api_audience/0,
1011
send_forbidden: &Neurow.PublicApi.Endpoint.send_forbidden/3,

neurow/test/jwt_helper.exs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ defmodule JwtHelper do
1616
conn |> put_req_header("authorization", "Bearer #{jwt_token}")
1717
end
1818

19-
def put_jwt_token_in_req_header_internal_api(conn, issuer \\ "test_issuer1") do
19+
def put_jwt_token_in_req_header_internal_api(
20+
conn,
21+
issuer \\ "test_issuer1",
22+
header_name \\ "authorization"
23+
) do
2024
conn
2125
|> put_req_header(
22-
"authorization",
26+
header_name,
2327
"Bearer #{compute_jwt_token_in_req_header_internal_api(issuer)}"
2428
)
2529
|> put_req_header("content-type", "application/json")

neurow/test/neurow/internal_api/endpoint_test.exs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule Neurow.InternalApi.EndpointTest do
1818
assert call.status == 200
1919
end
2020

21-
test "other routes requires a JWT token" do
21+
test "other routes requires a JWT sent in authorization header" do
2222
conn = conn(:get, "/foo")
2323
call = Neurow.InternalApi.Endpoint.call(conn, [])
2424
assert call.status == 403
@@ -31,6 +31,19 @@ defmodule Neurow.InternalApi.EndpointTest do
3131
assert call.status == 404
3232
end
3333

34+
test "other routes requires a JWT sent in x-interservice-authorization header" do
35+
conn = conn(:get, "/foo")
36+
call = Neurow.InternalApi.Endpoint.call(conn, [])
37+
assert call.status == 403
38+
39+
conn =
40+
conn(:get, "/foo")
41+
|> put_jwt_token_in_req_header_internal_api("test_issuer1", "x-interservice-authorization")
42+
43+
call = Neurow.InternalApi.Endpoint.call(conn, [])
44+
assert call.status == 404
45+
end
46+
3447
describe "POST /v1/subscribe" do
3548
test "returns a 403 if called without a JWT token" do
3649
body =

neurow/test/neurow/jwt_auth_plug_test.exs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ defmodule Neurow.JwtAuthPlugTest do
1515
{:ok,
1616
default_opts:
1717
Neurow.JwtAuthPlug.init(%{
18+
credential_headers: ["authorization"],
1819
audience: @test_audience,
1920
verbose_authentication_errors: true,
2021
max_lifetime: 60 * 2,
@@ -43,7 +44,8 @@ defmodule Neurow.JwtAuthPlugTest do
4344

4445
response =
4546
Neurow.JwtAuthPlug.call(
46-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
47+
conn(:get, "/test")
48+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
4749
opts
4850
)
4951

@@ -150,7 +152,8 @@ defmodule Neurow.JwtAuthPlugTest do
150152

151153
response =
152154
Neurow.JwtAuthPlug.call(
153-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
155+
conn(:get, "/test")
156+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
154157
opts
155158
)
156159

@@ -168,7 +171,8 @@ defmodule Neurow.JwtAuthPlugTest do
168171

169172
response =
170173
Neurow.JwtAuthPlug.call(
171-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
174+
conn(:get, "/test")
175+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
172176
opts
173177
)
174178

@@ -189,7 +193,8 @@ defmodule Neurow.JwtAuthPlugTest do
189193

190194
response =
191195
Neurow.JwtAuthPlug.call(
192-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_2),
196+
conn(:get, "/test")
197+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_2),
193198
opts
194199
)
195200

@@ -248,7 +253,8 @@ defmodule Neurow.JwtAuthPlugTest do
248253

249254
response =
250255
Neurow.JwtAuthPlug.call(
251-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_2_jwk),
256+
conn(:get, "/test")
257+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_2_jwk),
252258
opts
253259
)
254260

@@ -268,7 +274,8 @@ defmodule Neurow.JwtAuthPlugTest do
268274

269275
response =
270276
Neurow.JwtAuthPlug.call(
271-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
277+
conn(:get, "/test")
278+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
272279
opts
273280
)
274281

@@ -286,7 +293,8 @@ defmodule Neurow.JwtAuthPlugTest do
286293

287294
response =
288295
Neurow.JwtAuthPlug.call(
289-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
296+
conn(:get, "/test")
297+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
290298
opts
291299
)
292300

@@ -304,7 +312,8 @@ defmodule Neurow.JwtAuthPlugTest do
304312

305313
response =
306314
Neurow.JwtAuthPlug.call(
307-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
315+
conn(:get, "/test")
316+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
308317
opts
309318
)
310319

@@ -322,7 +331,8 @@ defmodule Neurow.JwtAuthPlugTest do
322331

323332
response =
324333
Neurow.JwtAuthPlug.call(
325-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
334+
conn(:get, "/test")
335+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
326336
opts
327337
)
328338

@@ -341,7 +351,8 @@ defmodule Neurow.JwtAuthPlugTest do
341351

342352
response =
343353
Neurow.JwtAuthPlug.call(
344-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
354+
conn(:get, "/test")
355+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
345356
opts
346357
)
347358

@@ -362,7 +373,8 @@ defmodule Neurow.JwtAuthPlugTest do
362373

363374
response =
364375
Neurow.JwtAuthPlug.call(
365-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
376+
conn(:get, "/test")
377+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
366378
opts
367379
)
368380

@@ -385,7 +397,8 @@ defmodule Neurow.JwtAuthPlugTest do
385397

386398
response =
387399
Neurow.JwtAuthPlug.call(
388-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
400+
conn(:get, "/test")
401+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
389402
opts
390403
)
391404

@@ -405,7 +418,8 @@ defmodule Neurow.JwtAuthPlugTest do
405418

406419
response =
407420
Neurow.JwtAuthPlug.call(
408-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
421+
conn(:get, "/test")
422+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
409423
opts
410424
)
411425

@@ -423,7 +437,8 @@ defmodule Neurow.JwtAuthPlugTest do
423437

424438
response =
425439
Neurow.JwtAuthPlug.call(
426-
conn(:get, "/test") |> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
440+
conn(:get, "/test")
441+
|> put_jwt_token_in_req_header(jwt_payload, @issuer_1_jwk_1),
427442
opts
428443
)
429444

0 commit comments

Comments
 (0)