Central Authentication Service is a very simple Single Sign On protocol. Here's a quick tl;dr. how it works.
CAS involves three parties:
/login
URL, including a query string parameter of the URL that CAS should
send the user back to after they authenticate with CAS (a "service URL").
https://accounts.cas.com/login?service=https://your-application.com/login-complete
ticket
query string parameter.ticket
and its service
URL
to the CAS server to verify, by making an HTTP request to the /validate
URL on CAS.
https://accounts.cas.com/verify?service=https://your-application.com/login-complete&ticket=1A2B3C
/verify
URL returns a simple plain text response:
yes\nname@example.com
-- it says "yes" or "no" on the first line indicating
if the ticket was correct, and the user's email address on the second line if
the login was successful.The web application now has the user's verified e-mail address confirmed through CAS and could set session cookies to mark them "logged in" on the application, create a web application account using their e-mail address, etc.
Example web app code in Python/Flask:
from flask import Flask, redirect, url_for, session
import requests
app = Flask(__name__)
# Config variables.
CAS_SERVER = "https://accounts.cas.com"
CAS_LOGIN_URL = CAS_SERVER + "/login"
CAS_VERIFY_URL = CAS_SERVER + "/validate"
# The service URL that CAS will send the user back to, on our
# web application, after they authenticate with CAS.
SERVICE_URL = "https://your-application.com/login-complete"
# (Python/Flask could determine this URL dynamically as follows):
# SERVICE_URL = url_for("login_complete", _external=True)
@app.route("/")
def index_page():
return """
<a href="/login">Sign in to this web application</a>
"""
@app.route("/login")
def login_begin():
# Start of the login process: redirect the user to CAS to authenticate.
# URL is like: https://accounts.cas.com/login?service=https://your-application.com/login-complete
return redirect(
CAS_LOGIN_URL + "?service=" + CAS_VERIFY_URL
)
@app.route("/login-complete")
def login_complete():
# This HTTP request includes a "ticket" query parameter.
ticket = request.args.get("ticket")
# Call the CAS server to verify the ticket.
r = requests.get(
CAS_VERIFY_URL,
params={
"ticket": ticket,
"service": SERVICE_URL,
}
)
# omitted: handle http errors, check if `r.ok` or r.status_code is 200, etc.
# Read the response from CAS validate url.
data = r.text # looks like "yes\nname@example.com" or "no\n"
lines = data.split("\n")
# Successful?
if lines[0] == "yes":
email = lines[1]
# User is authenticated, mark them logged in or whatever.
session["logged_in"] = True
session["user_email"] = email
return "Login successful, welcome %s!" % email
return "Login failed."
The CAS Server itself is just a simple web application that has user accounts and session cookies to log users in and remember them.
Suppose the CAS server has a database with these tables:
The logic of the CAS endpoints works as follows:
service
: the URL to redirect the user back to after login (this is a URL
on the web application that is wanting to authenticate the user)service
parameter originally given to "/login"service
URL with the ticket
query parameter.service
: the very same service URL originally given to /login
above.ticket
: the ticket string given to the service URL.no\n
no\n
service
query parameter does NOT match the Service URL in the
Tickets table for that ticket: error, return no\n
yes\n
and the email address from the
Tickets table.0.1902s
.