11

Some Updates On “LDAP Authentication With Phoenix”

 3 years ago
source link: https://onor.io/2017/08/07/some-updates-on-ldap-authentication-with-phoenix/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Some Updates On “LDAP Authentication With Phoenix”

There’s an excellent write-up on authenticating users against an LDAP database with Phoenix which was created by Richard Nyström.  For some reason even though it’s barely a year old, there seem to be a few points that are either out of date or simply incorrect. I worked through his example and I wanted to share a few amendments to his original code in the interests of other developers who may want to use LDAP with Phoenix.

First the set up of Phoenix

mix phx.new ldap_example # was mix phoenix.new ldap_example
...
Fetch and install dependencies? [Yn] Y
cd ldap_example
mix ecto.create (configure your db in config/dev.exs if needed)
mix phx.gen.schema User users username:string name:string email:string
# was
# mix phoenix.gen.model User users username:string name:string email:string
mix ecto.migrate

Next change is in the session_controller.ex file:

#was LdapExample.SessionController
defmodule LdapExampleWeb.SessionController do
#was LdapExample.Web, :controller
use LdapExampleWeb, :controller
alias LdapExample.{User, Repo, Ldap}
def new(conn, _params) do
render conn, "new.html", changeset: User.login_changeset
end
def create(conn, %{"user" => params}) do
username = params["username"]
password = params["password"]
case Ldap.authenticate(username, password) do
:ok -> handle_sign_in(conn, username)
_ -> handle_error(conn)
end
end
defp handle_sign_in(conn, username) do
{:ok, user} = insert_or_update_user(username)
conn
|> put_flash(:info, "Logged in.")
|> Guardian.Plug.sign_in(user)
|> redirect(to: page_path(conn, :index))
end
defp insert_or_update_user(username) do
{:ok, ldap_entry} = Ldap.get_by_uid(username)
user_attributes = Ldap.to_map(ldap_entry)
user = Repo.get_by(User, username: username)
changeset =
case user do
nil -> User.changeset(%User{}, user_attributes)
_ -> User.changeset(user, user_attributes)
end
Repo.insert_or_update changeset
end
defp handle_error(conn) do
conn
|> put_flash(:error, "Wrong username or password")
|> redirect(to: page_path(conn, :new))
end
def delete(conn, _params) do
Guardian.Plug.sign_out(conn)
|> put_flash(:info, "Logged out successfully.")
|> redirect(to: "/")
end
end

The changes to user.ex are not made in the web/model/user.ex; rather they’re made in the existing user.ex file.

And finally a change to session_view.ex

#was LdapExample.SessionView
defmodule LdapExampleWeb.SessionView do
use LdapExampleWeb, :view
end

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK