Skip to content

sparkcyf/cas-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CAS Proxy

Proxy CAS3 authentication to an OAuth2/OIDC-style client such as Keycloak.

+----------------+     +---------------------+     +-------------------+
|                |     |                     |     |                   |
|   Keycloak     |     |      cas-proxy      |     |    CAS Server     |
|                |     |                     |     |                   |
+-------+--------+     +---------+-----------+     +-------+-----------+
        |                      |                           |
        |  /authorize          |                           |
        +--------------------->|                           |
        |                      | /cas/login?service=...    |
        |                      |-------------------------->|
        |                      |                           |
        |                      | callback ticket           |
        |                      |<--------------------------|
        |                      | /callback?ticket=...      |
        |                      +-------------------------->|
        |                      |                           |
        |                      | serviceValidate           |
        |                      |-------------------------->|
        |                      | CAS attributes            |
        |                      |<--------------------------|
        |                      |                           |
        |       auth code      |                           |
        |<---------------------+                           |
        |                      |                           |
        |   /token             |                           |
        +--------------------->|                           |
        |                      |                           |
        |      tokens          |                           |
        |<---------------------+                           |
        |                      |                           |
        |   /userinfo          |                           |
        +--------------------->|                           |
        |                      |                           |
        |      user info       |                           |
        |<---------------------+                           |

What Changed

  • Runtime state now uses SQLite instead of process-local dictionaries.
  • Auth codes are consumed once inside a transaction.
  • Session, auth code, and token records have expirations and are cleaned up.
  • Redirect URI validation checks scheme, host, port, and optional path instead of using startswith.
  • CAS validation uses timeouts, network error handling, and defusedxml.
  • Cookies use HttpOnly, SameSite, Secure, and max_age.
  • /userinfo handles missing or malformed bearer tokens cleanly.
  • Configuration can still come from config.py, with environment variables able to override it.

Install

python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
cp config.example.py config.py

Edit config.py before starting the service. Do not commit config.py; it is ignored by git.

Configuration

The old config.py style is still supported. This minimal configuration matches the original deployment shape:

CAS_LOGIN_URL = "https://cas.sustech.edu.cn/cas/login"
CAS_VALIDATE_URL = "https://cas.sustech.edu.cn/cas/p3/serviceValidate"
SERVICE_URL = "https://cas-proxy.cra.moe/callback"

REDIRECT_URI_ALLOWLIST = ["https://sso.cra.ac.cn"]

CLIENT_ID = "cra-cas-proxy"
CLIENT_SECRET = "replace-with-a-new-random-secret"
SECRET_KEY = "replace-with-a-long-random-jwt-signing-secret"

REDIRECT_URL_MATCH = "https://sso.cra.ac.cn" is also accepted for compatibility, but REDIRECT_URI_ALLOWLIST is preferred.

Useful optional settings:

ACCESS_TOKEN_EXPIRY = 1800
AUTH_CODE_EXPIRY = 300
SESSION_EXPIRY = 600
DATABASE_PATH = "cas_proxy.sqlite3"
ISSUER = "cas-proxy"
CAS_REQUEST_TIMEOUT = 8.0
COOKIE_SECURE = True
COOKIE_SAMESITE = "Lax"
HOST = "127.0.0.1"
PORT = 59084
REQUIRE_TOKEN_REDIRECT_URI = False

Any setting can also be provided as an environment variable with the same name. Environment variables take precedence over config.py.

Running

For local testing:

python casproxy.py

For production, run behind a reverse proxy and use multiple workers if needed:

gunicorn -w 4 -b 127.0.0.1:59084 casproxy:app

SQLite is opened in WAL mode, so multiple Gunicorn workers can share the same DATABASE_PATH on one host. If you later run several machines, move the state store to Redis or another shared backend.

Security Notes

  • Rotate CLIENT_SECRET and SECRET_KEY if they have been pasted into chat, logs, tickets, or shell history.
  • Keep COOKIE_SECURE = True in production.
  • SECRET_KEY signs JWTs; use a long random value rather than a short UUID.
  • Keep SERVICE_URL exactly equal to the CAS callback URL registered with CAS.
  • Keep the redirect allowlist as narrow as possible.

Health Check

curl http://127.0.0.1:59084/healthz

Tests

After installing dependencies:

python -m unittest discover -s tests

About

convert cas3 auth server to oidc style

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors