How do a connection between cas and phoenix?
This post I want to talk about :ueberauth_cas, since I haven’t found a example to be used.
ueberauth_cas
Is a central Authentication for a ticket from any cas authentication View github: https://github.com/marceldegraaf/ueberauth_cas
Install dependencies
You should know, this dependency needs to ueberauth to its functio, than you have a little information about this dependency (ueberauth): https://github.com/ueberauth/ueberauth
First Step
Add dependencies
## Application
def application do
[
mod: {ExampleUeberauthCas.Application, []},
extra_applications: [:logger, :runtime_tools, :httpoison, :ueberauth, :ueberauth_cas]
]
end
## Your deps
defp deps do
[
{:phoenix, "~> 1.3.2"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.2"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.10"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:cowboy, "~> 1.0"},
{:httpoison, "~> 1.2", override: true},
{:ueberauth, "~> 0.4"},
{:ueberauth_cas, "~> 1.1.0", override: true}
]
end
We have to add override in true, because cas dependency needs to httpoison in version 0.3 but in this test was able to check with as correct functionally in its current version.
Second Step
We add the configuration in your config, dev or prod, according to the case
config :ueberauth, Ueberauth,
providers: [
cas: {Ueberauth.Strategy.CAS, [
base_url: "https://apr-test.ebc.edu.mx/casad",
callback: "http://localhost:4000/",
callback_url: "http://localhost:4000/auth/cas/callback"
]}]
Third Step
We crate a controller like to auth_controller.ex
defmodule ExampleUeberauthCasWeb.AuthController do
@moduledoc """
Auth controller responsible for handling Ueberauth responses
"""
use ExampleUeberauthCasWeb, :controller
plug Ueberauth
alias Floki
Plug.Conn
def login(conn, _params, _current_user, _claims) do
conn
|> Ueberauth.Strategy.CAS.handle_request!
end
def callback(%{assigns: %{ueberauth_failure: _fails}} = conn, _params) do
conn
|> put_flash(:error, "Failed to authenticate.")
|> redirect(to: "/")
end
def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
conn
|> put_flash(:info, "Successfully authenticated.")
|> put_session(:current_user, auth)
|> redirect(to: "/")
end
def delete(conn, _params) do
conn
|> put_flash(:info, "You have been logged out!")
|> configure_session(drop: true)
|> redirect(external: "https://apr-test.ebc.edu.mx/casad/logout")
end
end
In my case I needed to add Floki dependency, because in producci贸n, phoenix was not compiling.
Fourth Step
We are near 馃檪, so we create our scope in your router.
scope "/auth", ExampleUeberauthCasWeb do
pipe_through [:browser]
get "/:provider", AuthController, :request
get "/:provider/callback", AuthController, :callback
delete "/:provider/logout", AuthController, :delete
get "/:provider/logout", AuthController, :delete
end
Method Request
it Is who goes to make petition to cas authentication
Method callback
It is where returned the information from cas authentication
Method delete
This case we create both methods, delete and get, because in some cases the form in html5 not supported method delete. is need to realize this, Ueberauth.Strategy.CAS saves in cache the token from cas authentication, so we need to delete session that is saved in phoenix.
This is enough to function, we can see in the url: http://localhost:4000/auth/cas
Plus:
you wan to everyone calls to controllers has to pass for this auth, then you should create a plug like this
In your plug custom
defmodule ExampleUeberauthCasWeb.Plug.Auth do
import Plug.Conn
import Phoenix.Controller
require Logger
def init(_opts) do
end
def call(%{private: %{plug_session: current_user}} = conn, _options) do
case current_user["current_user"] do
nil ->
Logger.info ":: Not Logger ::: "
conn
|> put_flash(:error, "You need to sign in or sign up before continuing.")
|> redirect(to: "/auth/cas")
|> halt()
_ ->
conn
|> put_flash(:ok, "You are sign on")
|> redirect(to: "/auth/cas")
|> halt()
end
end
def call(conn, _params) do
IO.inspect conn
Logger.info ":: Error ::: "
halt(conn)
conn
end
end
In your router you had to add pipeline like this:
pipeline :auth do
plug ExampleUeberauthCasWeb.Plug.Auth
end
Now in your scope is enough add the pipeline
scope "/", ExampleUeberauthCasWeb do
pipe_through [:browser, :auth] # Use the default browser stack
get "/", PageController, :index
end
This way every to call some controller, will be check the session.
Conclusion
You remember, phoenix saves the session in chache of the broswer for a limit time, if you want to make a correct logout, you should to do in both platforms (Your application and cas application ), As I said previously