I'm having a similar problem Like this one. In my case I'm trying to do all the logic on the API side. API Looks ok and rejecting invalid users already work fine. The problem is authenticating with attributes returnes from the API. FreeRADIUS's rest module issues an update comand after realyzing that the response returns some attributes and fails to authenticate.
My config looks like this:
authorize {
rest
if (ok) {
update control {
Auth-Type := rest
}
}
}
Logic is: Check in authorize if user exits (APi respond with Status code 204) then perform authenticate. Authenticate sends username & password to API. API checks some info and then returns with Status code 200 and attributes in correct JSON format if everything is ok.
Curiosly if I set my API to respond with Status code 204 instead of 200 user is authenticated normaly (but without any attributes)
Log:
(0) Received Access-Request Id 91 from 127.0.0.1:57293 to 127.0.0.1:1812 length 75
(0) User-Name = "admin"
(0) User-Password = "1234"
(0) NAS-IP-Address = 10.99.99.1
(0) NAS-Port = 0
(0) Message-Authenticator = 0x506aba80999c45a4c52d7c5544073969
(0) # Executing section authorize from file /usr/local/etc/raddb/sites-enabled/nano
(0) authorize {
rlm_rest (rest): Reserved connection (0)
(0) rest: Expanding URI components
(0) rest: EXPAND http://127.0.0.1:4000
(0) rest: --> http://127.0.0.1:4000
(0) rest: EXPAND /check/%{User-Name}
(0) rest: --> /check/admin
(0) rest: Sending HTTP GET to "http://127.0.0.1:4000/check/admin"
(0) rest: Processing response header
(0) rest: Status : 204 (No Content)
rlm_rest (rest): Released connection (0)
Need 5 more connections to reach 10 spares
rlm_rest (rest): Opening additional connection (5), 1 of 27 pending slots used
rlm_rest (rest): Connecting to "http://127.0.0.1:4000/"
(0) [rest] = ok
(0) if (ok) {
(0) if (ok) -> TRUE
(0) if (ok) {
(0) update control {
(0) Auth-Type := rest
(0) } # update control = noop
(0) } # if (ok) = noop
(0) } # authorize = ok
(0) Found Auth-Type = rest
(0) # Executing group from file /usr/local/etc/raddb/sites-enabled/nano
(0) authenticate {
rlm_rest (rest): Reserved connection (1)
(0) rest: Expanding URI components
(0) rest: EXPAND http://127.0.0.1:4000
(0) rest: --> http://127.0.0.1:4000
(0) rest: EXPAND /auth/%{User-Name}/%{User-Password}
(0) rest: --> /auth/admin/1234
(0) rest: Sending HTTP GET to "http://127.0.0.1:4000/auth/admin/1234"
(0) rest: Processing response header
(0) rest: Status : 200 (OK)
(0) rest: Type : json (application/json)
(0) rest: Parsing attribute "WISPr-Bandwidth-Max-Down"
(0) rest: EXPAND 3000
(0) rest: --> 3000
(0) rest: WISPr-Bandwidth-Max-Down := 3000
(0) rest: Parsing attribute "WISPr-Bandwidth-Max-Up"
(0) rest: EXPAND 1000
(0) rest: --> 1000
(0) rest: WISPr-Bandwidth-Max-Up := 1000
rlm_rest (rest): Released connection (1)
(0) [rest] = updated
(0) } # authenticate = updated
(0) Failed to authenticate the user
(0) Using Post-Auth-Type Reject
(0) Post-Auth-Type sub-section not found. Ignoring.
(0) # Executing group from file /usr/local/etc/raddb/sites-enabled/nano
(0) Delaying response for 1.000000 seconds
Waking up in 0.3 seconds.
Waking up in 0.6 seconds.
(0) Sending delayed response
(0) Sent Access-Reject Id 91 from 127.0.0.1:1812 to 127.0.0.1:57293 length 44
(0) WISPr-Bandwidth-Max-Down = 3000
(0) WISPr-Bandwidth-Max-Up = 1000
Waking up in 3.9 seconds.
(0) Cleaning up request packet ID 91 with timestamp +9
Thanks in advance for any hints.
Yeah, I think I fixed that in v4.0.x. It was some legacy issue with 'updated' not being an acceptable return code.
You can override the return code and the priority with the following:
authenticate {
Auth-Type rest {
rest {
updated = 1
}
if (updated) {
ok
}
}
}
To explain - Each return code 'ok', 'noop', 'fail' etc... has different priorities and actions depending on the section. The return code of the module only updates the section return code if it has a higher priority.
There's a magic priority 'return' which causes the server to instantly exit the section. It's set for most return codes in the authenticate section.
We need to override that priority for the call to the rest module, so the interpreter doesn't return out of authenticate without evaluating the condition if (updated)
. In the above example we set the priority of updated to 1, ensuring it can be overwritten later.