Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apisix/plugins/cas-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ function _M.access(conf, ctx)
local _, user = unpack_entry(entry)
core.log.info("cas-auth: SLO session deleted for user=", user or "<unknown>")
end
-- SLO callback ends here; never proxy the IdP's logout POST upstream
return ngx.HTTP_OK
else
local opts = session_opts(conf)
local session_id = get_cookie(ctx, opts.cookie_name)
Expand Down
2 changes: 2 additions & 0 deletions docs/en/latest/plugins/cas-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ Once this is done, the user is redirected to the original URL they wanted to vis

Later, the user could visit `logout_uri` to start logout process. The user would be redirected to `idp_uri` to do logout.

The IdP may also send a single logout (SLO) `POST` request to `cas_callback_uri`. The Plugin handles such requests itself (invalidating the matching session) and never forwards them to the upstream.

Note that, `cas_callback_uri` and `logout_uri` should be
either full qualified address (e.g. `http://127.0.0.1:9080/anything/logout`),
or path only (e.g. `/anything/logout`), but it is recommended to be path only to keep consistent.
Expand Down
71 changes: 71 additions & 0 deletions t/plugin/cas-auth.t
Original file line number Diff line number Diff line change
Expand Up @@ -878,3 +878,74 @@ passed
}
--- response_body
passed



=== TEST 21: add route whose upstream is a closed port for the SLO fall-through test
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test

local code, body = t('/apisix/admin/routes/cas-slo-noproxy',
ngx.HTTP_PUT,
[[{
"methods": ["GET", "POST"],
"host": "127.0.0.21",
"priority": 10,
"plugins": {
"cas-auth": {
"idp_uri": "http://127.0.0.1:8080/realms/test/protocol/cas",
"cas_callback_uri": "/cas_callback",
"logout_uri": "/logout",
"cookie": {
"secret": "0123456789abcdef0123456789abcdef",
"secure": false
}
}
},
"upstream": {
"nodes": {"127.0.0.1:1": 1},
"type": "roundrobin"
},
"uri": "/*"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed



=== TEST 22: well-formed SLO POST stops at the plugin and is never proxied upstream
--- config
location /t {
content_by_lua_block {
local http = require "resty.http"
local httpc = http.new()
local base = "http://127.0.0.1:" .. ngx.var.server_port

-- A POST carrying a valid SessionIndex must be terminated by the
-- plugin (200), not fall through to the upstream. The upstream is a
-- closed port, so any fall-through would surface as a 502.
local res, err = httpc:request_uri(base .. "/cas_callback", {
method = "POST",
headers = { ["Host"] = "127.0.0.21" },
body = "<samlp:SessionIndex>ST-no-such-session</samlp:SessionIndex>",
})
assert(res, "request failed: " .. tostring(err))
assert(res.status == 200,
"expected 200 from plugin, got " .. res.status ..
" (non-200 means the SLO POST was proxied upstream)")

ngx.say("passed")
}
}
--- response_body
passed
Loading