pow-auth / assent

Multi-provider framework in Elixir
https://powauth.com
MIT License
406 stars 47 forks source link

AssentJWT adapter returns unexpected value #128

Closed janpieper closed 1 year ago

janpieper commented 1 year ago

The possible return values of Assent.JWTAdapter.AssentJWT.verify/3 do not match the callback definition of Assent.JWTAdapter.verify/3 :thinking:

Here is the callback definition: https://github.com/pow-auth/assent/blob/d2c4675473204cbb6bba5ec3e49f225342c011d4/lib/assent/jwt_adapter.ex#L25

Calling Assent.JWTAdapter.AssentJWT.verify/2 can also return just :error :astonished: Have a look into the example below:

token = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhc3NlbnQtaXNzdWUiLCJleHAiOjE3MTk0ODk5MDcsInN1YiI6IjQyIn0.o3Lijaa_Q5m1Tr7A6myopsdtO771SlVu9rK-ElIqdYcj5eo5PochP3cqG7NFw76TqyRMdNwkr-OQevAWUbcireZ-dSKtkhtYm91M2sVM_RI5s7LTfdbUTHEleCAg_x0pC1mkDRmKSKBPuooEKypIl6P6ME0GogC_4SthzYRx3gks6m9TNI8wCzRhOaGuLEvnOm8KoQXpreVLfibe_C_v30AiJVzxMoqskQKJ9hagE34I9SB6ut3_ZsczMisjXe5cGLcsWSctAoi-JaIqUk3pMyfgUVVvt8ZzbV2LvqPz2O1vOAT-QDui68szYFAJh9IaNbwVC9QdLmthdg01DLYrA"

secret = %{
  "alg" => "RS256",
  "e" => "AQAB",
  "kid" => "example",
  "kty" => "RSA",
  "n" => "g5IE_tFgft5wRYPwivPY4QpNc6IpbZv5w24tW2rKdS74ntwhPQo38yahAOUujTAbpUvN3motDtJOkjov9O6fxhFkjOEA4zxXFGxHWyMwloRjNen9uScbi88EuVaSuTWKoq4C9FE650222QrtU0SImMSgi166sbTbi5bvS9hanSphksmw8vdVff56aFE5jOpVXNEoFoj3CFTRfesIhht9qXJp-HFbbSkDcyeQ1Y5rv5nzKQXMONTxxhV-qaJ03BNLxFVOP9eqeVTUHQoQ262qpbz-3qRWxxqy5Q2V0g4yk-IJPV2u6yNd5SojsRK3V5YIC3b0_VuDXN_we0o-sOjESQ",
  "use" => "sig"
}

Assent.JWTAdapter.AssentJWT.verify(id_token, secret, [json_library: Jason])

The :error is caused by a broken token I passed in. When using a valid token (see below), you get an {:ok, _} tuple.

eyJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhc3NlbnQtaXNzdWUiLCJleHAiOjE3MTk0ODk5MDcsInN1YiI6IjQyIn0.Zo3Lijaa_Q5m1Tr7A6myopsdtO771SlVu9rK-ElIqdYcj5eo5PochP3cqG7NFw76TqyRMdNwkr-OQevAWUbcireZ-dSKtkhtYm91M2sVM_RI5s7LTfdbUTHEleCAg_x0pC1mkDRmKSKBPuooEKypIl6P6ME0GogC_4SthzYRx3gks6m9TNI8wCzRhOaGuLEvnOm8KoQXpreVLfibe_C_v30AiJVzxMoqskQKJ9hagE34I9SB6ut3_ZsczMisjXe5cGLcsWSctAoi-JaIqUk3pMyfgUVVvt8ZzbV2LvqPz2O1vOAT-QDui68szYFAJh9IaNbwVC9QdLmthdg01DLYrA
danschultzer commented 1 year ago

Thanks @janpieper, great catch! It got fixed with #130. Running through the three possible states here, invalid JWT, verified, and not verified:

iex(1)> token = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhc3NlbnQtaXNzdWUiLCJleHAiOjE3MTk0ODk5MDcsInN1YiI6IjQyIn0.o3Lijaa_Q5m1Tr7A6myopsdtO771SlVu9rK-ElIqdYcj5eo5PochP3cqG7NFw76TqyRMdNwkr-OQevAWUbcireZ-dSKtkhtYm91M2sVM_RI5s7LTfdbUTHEleCAg_x0pC1mkDRmKSKBPuooEKypIl6P6ME0GogC_4SthzYRx3gks6m9TNI8wCzRhOaGuLEvnOm8KoQXpreVLfibe_C_v30AiJVzxMoqskQKJ9hagE34I9SB6ut3_ZsczMisjXe5cGLcsWSctAoi-JaIqUk3pMyfgUVVvt8ZzbV2LvqPz2O1vOAT-QDui68szYFAJh9IaNbwVC9QdLmthdg01DLYrA"
"eyJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhc3NlbnQtaXNzdWUiLCJleHAiOjE3MTk0ODk5MDcsInN1YiI6IjQyIn0.o3Lijaa_Q5m1Tr7A6myopsdtO771SlVu9rK-ElIqdYcj5eo5PochP3cqG7NFw76TqyRMdNwkr-OQevAWUbcireZ-dSKtkhtYm91M2sVM_RI5s7LTfdbUTHEleCAg_x0pC1mkDRmKSKBPuooEKypIl6P6ME0GogC_4SthzYRx3gks6m9TNI8wCzRhOaGuLEvnOm8KoQXpreVLfibe_C_v30AiJVzxMoqskQKJ9hagE34I9SB6ut3_ZsczMisjXe5cGLcsWSctAoi-JaIqUk3pMyfgUVVvt8ZzbV2LvqPz2O1vOAT-QDui68szYFAJh9IaNbwVC9QdLmthdg01DLYrA"

iex(2)> secret = %{
...(2)>   "alg" => "RS256",
...(2)>   "e" => "AQAB",
...(2)>   "kid" => "example",
...(2)>   "kty" => "RSA",
...(2)>   "n" => "g5IE_tFgft5wRYPwivPY4QpNc6IpbZv5w24tW2rKdS74ntwhPQo38yahAOUujTAbpUvN3motDtJOkjov9O6fxhFkjOEA4zxXFGxHWyMwloRjNen9uScbi88EuVaSuTWKoq4C9FE650222QrtU0SImMSgi166sbTbi5bvS9hanSphksmw8vdVff56aFE5jOpVXNEoFoj3CFTRfesIhht9qXJp-HFbbSkDcyeQ1Y5rv5nzKQXMONTxxhV-qaJ03BNLxFVOP9eqeVTUHQoQ262qpbz-3qRWxxqy5Q2V0g4yk-IJPV2u6yNd5SojsRK3V5YIC3b0_VuDXN_we0o-sOjESQ",
...(2)>   "use" => "sig"
...(2)> }
%{
  "alg" => "RS256",
  "e" => "AQAB",
  "kid" => "example",
  "kty" => "RSA",
  "n" => "g5IE_tFgft5wRYPwivPY4QpNc6IpbZv5w24tW2rKdS74ntwhPQo38yahAOUujTAbpUvN3motDtJOkjov9O6fxhFkjOEA4zxXFGxHWyMwloRjNen9uScbi88EuVaSuTWKoq4C9FE650222QrtU0SImMSgi166sbTbi5bvS9hanSphksmw8vdVff56aFE5jOpVXNEoFoj3CFTRfesIhht9qXJp-HFbbSkDcyeQ1Y5rv5nzKQXMONTxxhV-qaJ03BNLxFVOP9eqeVTUHQoQ262qpbz-3qRWxxqy5Q2V0g4yk-IJPV2u6yNd5SojsRK3V5YIC3b0_VuDXN_we0o-sOjESQ",
  "use" => "sig"
}

iex(3)> Assent.JWTAdapter.AssentJWT.verify(token, secret, [json_library: Jason])   
{:error,
 %Assent.JWTAdapter.AssentJWT.Error{
   message: "Failed to decode signature",
   reason: "Invalid Base64URL",
   data: "o3Lijaa_Q5m1Tr7A6myopsdtO771SlVu9rK-ElIqdYcj5eo5PochP3cqG7NFw76TqyRMdNwkr-OQevAWUbcireZ-dSKtkhtYm91M2sVM_RI5s7LTfdbUTHEleCAg_x0pC1mkDRmKSKBPuooEKypIl6P6ME0GogC_4SthzYRx3gks6m9TNI8wCzRhOaGuLEvnOm8KoQXpreVLfibe_C_v30AiJVzxMoqskQKJ9hagE34I9SB6ut3_ZsczMisjXe5cGLcsWSctAoi-JaIqUk3pMyfgUVVvt8ZzbV2LvqPz2O1vOAT-QDui68szYFAJh9IaNbwVC9QdLmthdg01DLYrA"
 }}

iex(4)> token = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhc3NlbnQtaXNzdWUiLCJleHAiOjE3MTk0ODk5MDcsInN1YiI6IjQyIn0.Zo3Lijaa_Q5m1Tr7A6myopsdtO771SlVu9rK-ElIqdYcj5eo5PochP3cqG7NFw76TqyRMdNwkr-OQevAWUbcireZ-dSKtkhtYm91M2sVM_RI5s7LTfdbUTHEleCAg_x0pC1mkDRmKSKBPuooEKypIl6P6ME0GogC_4SthzYRx3gks6m9TNI8wCzRhOaGuLEvnOm8KoQXpreVLfibe_C_v30AiJVzxMoqskQKJ9hagE34I9SB6ut3_ZsczMisjXe5cGLcsWSctAoi-JaIqUk3pMyfgUVVvt8ZzbV2LvqPz2O1vOAT-QDui68szYFAJh9IaNbwVC9QdLmthdg01DLYrA"
"eyJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhc3NlbnQtaXNzdWUiLCJleHAiOjE3MTk0ODk5MDcsInN1YiI6IjQyIn0.Zo3Lijaa_Q5m1Tr7A6myopsdtO771SlVu9rK-ElIqdYcj5eo5PochP3cqG7NFw76TqyRMdNwkr-OQevAWUbcireZ-dSKtkhtYm91M2sVM_RI5s7LTfdbUTHEleCAg_x0pC1mkDRmKSKBPuooEKypIl6P6ME0GogC_4SthzYRx3gks6m9TNI8wCzRhOaGuLEvnOm8KoQXpreVLfibe_C_v30AiJVzxMoqskQKJ9hagE34I9SB6ut3_ZsczMisjXe5cGLcsWSctAoi-JaIqUk3pMyfgUVVvt8ZzbV2LvqPz2O1vOAT-QDui68szYFAJh9IaNbwVC9QdLmthdg01DLYrA"

iex(5)> Assent.JWTAdapter.AssentJWT.verify(token, secret, [json_library: Jason])
{:ok,
 %{
   header: %{"alg" => "RS256", "kid" => "example", "typ" => "JWT"},
   signature: <<102, 141, 203, 138, 54, 154, 253, 14, 102, 213, 58, 251, 3, 169,
     178, 162, 155, 29, 180, 238, 251, 213, 41, 85, 187, 218, 202, 248, 73, 72,
     169, 214, 28, 143, 151, 168, 228, 250, 28, 132, 253, 220, 168, 110, 205,
     23, ...>>,
   claims: %{"aud" => "assent-issue", "exp" => 1719489907, "sub" => "42"},
   verified?: true
 }}

iex(6)> Assent.JWTAdapter.AssentJWT.verify(token, nil, [json_library: Jason])   
{:ok,
 %{
   header: %{"alg" => "RS256", "kid" => "example", "typ" => "JWT"},
   signature: <<102, 141, 203, 138, 54, 154, 253, 14, 102, 213, 58, 251, 3, 169,
     178, 162, 155, 29, 180, 238, 251, 213, 41, 85, 187, 218, 202, 248, 73, 72,
     169, 214, 28, 143, 151, 168, 228, 250, 28, 132, 253, 220, 168, 110, 205,
     23, ...>>,
   claims: %{"aud" => "assent-issue", "exp" => 1719489907, "sub" => "42"},
   verified?: false
 }}

Sorry for the long wait!