View Source PhoenixApiToolkit.Security.Oauth2Plug (Phoenix API Toolkit v3.1.2)
Plug to verify an Oauth2 JWT. The JWT must be passed to the application in the authorization
request header prefixed with Bearer:
. The Plug must be configured with a set of JSON Web Keys used to
sign the JWT's, a whitelist of algorithms that may be used to sign the JWT and the expected issuer.
The optional dummy_verify
setting can be used to skip JWT verification for development and testing.
Requires :jose
dependency in your mix.exs file.
The most important setting is keyset
, in which a base64-encoded JSON list of JWK's must be provided. In order
to make the parsing work reliably, do the encoding in IEx or use echo 'keylist' | base64
in bash.
This plug verifies the token's signature, issuer and expiration timestamp.
Depending on the Oauth2 provider used, additional token claims should be verified.
According to the Oauth2 spec, the "aud" claim must always be verified, for example. In practice, however,
not all Oauth2 implementations adhere to the specification by including this claim in their tokens,
so that's why verification of "aud" and other claims is not handled by default by this plug. Please refer
to your Oauth2 provider's instructions about verifying token claims and take a look at
PhoenixApiToolkit.Security.Plugs
for additional claim verification plugs.
If the token is invalid for any reason, PhoenixApiToolkit.Security.Oauth2TokenVerificationError
is raised,
resulting in a 401 Unauthorized response.
usage-example
Usage example
plug Elixir.PhoenixApiToolkit.Security.Oauth2Plug,
keyset: "W3siYWxnIjoiUlMyNTYiLCJlIjoiQ",
exp_iss: "https://my_oauth2_auth_server",
dummy_verify: false,
alg_whitelist: ["RS256"]
results-examples
Results examples
use Plug.Test
import PhoenixApiToolkit.TestHelpers
alias PhoenixApiToolkit.Security.Oauth2Plug
@jwt_defaults %{
jwk: gen_jwk(),
jws: gen_jws(),
payload: gen_payload(iss: "http://my-oauth2-provider")
}
def opts do
Oauth2Plug.init(
lazy_keyset: fn -> test_jwks() |> Oauth2Plug.process_jwks() end,
lazy_exp_iss: fn -> @jwt_defaults.payload["iss"] end,
dummy_verify: false,
alg_whitelist: ["RS256"]
)
end
a correctly signed request is passed through, with the JWT's payload and JWS assigned
iex> conn = conn(:get, "/")
iex> jwt = gen_jwt(@jwt_defaults)
iex> result = conn |> put_jwt(jwt) |> Oauth2Plug.call(opts())
iex> result == conn |> put_jwt(jwt) |> assign(:jwt, result.assigns.jwt) |> assign(:jws, result.assigns.jws) |> assign(:raw_jwt, result.assigns.raw_jwt)
true
# requests that are noncompliant result in an Oauth2TokenVerificationError
iex> conn(:get, "/") |> Oauth2Plug.call(opts())
** (PhoenixApiToolkit.Security.Oauth2TokenVerificationError) Oauth2 token invalid: missing authorization header
iex> conn(:get, "/") |> put_jwt("invalid") |> Oauth2Plug.call(opts())
** (PhoenixApiToolkit.Security.Oauth2TokenVerificationError) Oauth2 token invalid: could not decode JWT
Link to this section Summary
Functions
Process a jwks string to pass to &call/2
.
Link to this section Functions
Process a jwks string to pass to &call/2
.