diff --git a/lib/oidcc/token.ex b/lib/oidcc/token.ex index 3a955ce..de3c969 100644 --- a/lib/oidcc/token.ex +++ b/lib/oidcc/token.ex @@ -310,6 +310,10 @@ defmodule Oidcc.Token do Useful if the issuer is shared between multiple applications, and the access token generated for a user at one client is used to validate their access at another client. + Validating an arbitrary JWT token (not an ID token) is not covered by the OpenID + Connect specification. Therefore the signing / encryption algorithms are not + derieved from the provider configuration, but must be provided by the caller. + ## Examples iex> {:ok, pid} = @@ -324,7 +328,7 @@ defmodule Oidcc.Token do ...> "client_secret" ...> ) ...> - ...> #Get JWT from Authorization header + ...> # Get JWT from Authorization header ...> jwt = "jwt" ...> ...> opts = %{ diff --git a/src/oidcc_token.erl b/src/oidcc_token.erl index 5e3a513..5bdaf79 100644 --- a/src/oidcc_token.erl +++ b/src/oidcc_token.erl @@ -958,6 +958,10 @@ Validates a generic JWT (such as an access token) from the given provider. Useful if the issuer is shared between multiple applications, and the access token generated for a user at one client is used to validate their access at another client. +Validating an arbitrary JWT token (not an ID token) is not covered by the OpenID +Connect specification. Therefore the signing / encryption algorithms are not +derieved from the provider configuration, but must be provided by the caller. + ## Examples ```erlang @@ -966,6 +970,12 @@ generated for a user at one client is used to validate their access at another c <<"client_id">>, <<"client_secret">>), %% Get Jwt from Authorization header +Jwt = <<"jwt">>, + +Opts = #{ + signing_algs => [<<"RS256">>] +}, + {ok, Claims} = oidcc:validate_jwt(Jwt, ClientContext, Opts). ``` @@ -995,6 +1005,14 @@ validate_jwt(Jwt, ClientContext, Opts) when is_map(Opts) -> SigningAlgs = maps:get(signing_algs, Opts, []), EncryptionAlgs = maps:get(encryption_algs, Opts, []), EncryptionEncs = maps:get(encryption_encs, Opts, []), + + case {SigningAlgs, EncryptionAlgs} of + {[], []} -> + error(badarg, [Jwt, ClientContext, Opts], []); + _ -> + ok + end, + ExpClaims = [{<<"iss">>, Issuer}], Jwks1 = case ClientJwks of diff --git a/test/oidcc/token_test.exs b/test/oidcc/token_test.exs index e216610..ec30170 100644 --- a/test/oidcc/token_test.exs +++ b/test/oidcc/token_test.exs @@ -227,4 +227,28 @@ defmodule Oidcc.TokenTest do ) end end + + describe inspect(&Oidcc.validate_jwt/3) do + test "throws badarg when leaving out signing & encryption parameters" do + pid = + start_supervised!( + {ProviderConfiguration.Worker, %{issuer: "https://erlef-test-w4a8z2.zitadel.cloud"}} + ) + + {:ok, client_context} = + ClientContext.from_configuration_worker( + pid, + @client_credentials_client_id, + @client_credentials_client_secret + ) + + assert_raise ArgumentError, fn -> + Oidcc.Token.validate_jwt( + "invalidtoken", + client_context, + %{} + ) + end + end + end end diff --git a/test/oidcc_token_test.erl b/test/oidcc_token_test.erl index eb2d655..cac486e 100644 --- a/test/oidcc_token_test.erl +++ b/test/oidcc_token_test.erl @@ -2199,8 +2199,8 @@ validate_jwt_test() -> oidcc_token:validate_jwt(JwtFun(WrongAudience), ClientContext, Opts) ), - ?assertEqual( - {error, no_matching_key}, + ?assertError( + badarg, oidcc_token:validate_jwt(JwtFun(WrongAudience), ClientContext, #{}) ),