Packages
ash_authentication
5.0.0-rc.6
5.0.0-rc.12
5.0.0-rc.11
5.0.0-rc.10
5.0.0-rc.9
5.0.0-rc.8
5.0.0-rc.7
5.0.0-rc.6
5.0.0-rc.5
5.0.0-rc.4
5.0.0-rc.3
5.0.0-rc.2
5.0.0-rc.1
5.0.0-rc.0
4.14.1
4.14.0
4.13.7
4.13.6
4.13.5
4.13.4
4.13.3
4.13.2
retired
4.13.1
retired
4.13.0
4.12.0
4.11.0
4.10.0
4.9.9
4.9.8
4.9.7
4.9.6
4.9.5
4.9.4
4.9.3
4.9.2
4.9.1
4.9.0
4.8.7
4.8.6
4.8.5
4.8.3
4.8.2
4.8.1
4.8.0
4.7.6
4.7.5
4.7.4
4.7.3
4.7.2
4.7.1
4.7.0
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.6
4.5.5
4.5.4
4.5.3
4.5.2
4.5.1
4.5.0
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.12
4.3.11
4.3.10
4.3.9
4.3.8
4.3.7
4.3.6
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
4.0.0-rc.6
4.0.0-rc.5
4.0.0-rc.3
4.0.0-rc.2
4.0.0-rc.1
4.0.0-rc.0
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.16
3.11.15
3.11.14
3.11.13
3.11.12
3.11.11
3.11.10
3.11.9
3.11.8
3.11.7
3.11.6
3.11.5
3.11.4
3.11.3
3.11.2
3.11.1
3.11.0
3.10.8
3.10.7
3.10.6
3.10.5
3.10.4
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.0
3.7.9
3.7.8
3.7.6
3.7.5
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.1
3.6.0
3.5.3
3.5.2
3.5.1
3.5.0
3.3.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.0
3.0.3
Authentication extension for the Ash Framework.
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/ash_authentication/strategies/oauth2/verifier.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defmodule AshAuthentication.Strategy.OAuth2.Verifier do
@moduledoc """
DSL verifier for oauth2 strategies.
"""
alias AshAuthentication.Strategy.OAuth2
alias Spark.Error.DslError
import AshAuthentication.Validations
@doc false
@spec verify(OAuth2.t(), map) :: :ok | {:error, Exception.t()}
def verify(strategy, dsl_state) do
with :ok <- validate_secret(strategy, :authorize_url),
:ok <- validate_secret(strategy, :client_id),
:ok <- validate_secret(strategy, :client_secret),
:ok <- validate_secret(strategy, :redirect_uri),
:ok <- validate_secret(strategy, :base_url),
:ok <- validate_secret(strategy, :token_url),
:ok <- validate_secret(strategy, :user_url),
:ok <- prevent_hijacking(dsl_state, strategy) do
if strategy.auth_method == :private_key_jwt do
validate_secret(strategy, :private_key)
else
:ok
end
end
end
@doc """
Verifies that an OAuth2-derived strategy isn't paired with a password strategy
unless a confirmation add-on is also present, which would otherwise allow an
attacker to hijack an existing local account by registering through the OAuth
provider with a matching identity field.
"""
@spec prevent_hijacking(map, OAuth2.t()) :: :ok | {:error, Exception.t()}
def prevent_hijacking(_dsl_state, %{prevent_hijacking?: false}), do: :ok
def prevent_hijacking(_dsl_state, %{registration_enabled?: false}), do: :ok
def prevent_hijacking(dsl_state, strategy) do
case Enum.find(
AshAuthentication.Info.authentication_strategies(dsl_state),
fn other_strategy ->
other_strategy.__struct__ == AshAuthentication.Strategy.Password &&
other_strategy.registration_enabled?
end
) do
nil ->
:ok
password_strategy ->
if has_confirmation_add_on?(dsl_state, password_strategy) do
:ok
else
{:error,
DslError.exception(
path: [:authentication, :strategies, strategy.name],
message: """
If you have an oauth2 strategy and a password strategy, you must also have a
confirmation add-on that monitors the password's identity field.
This is to prevent from account hijacking. If the field used in your password strategy is not
an email field, you can set `prevent_hijacking?: false` in your oauth strategy.
For more information, see the confirmation tutorial on hexdocs.
"""
)}
end
end
end
defp has_confirmation_add_on?(dsl_state, password_strategy) do
Enum.any?(AshAuthentication.Info.authentication_add_ons(dsl_state), fn add_on ->
add_on.__struct__ == AshAuthentication.AddOn.Confirmation &&
password_strategy.identity_field in add_on.monitor_fields
end)
end
end