caddy-security
caddy-security copied to clipboard
breakfix: Adding groups to scopes ends in to many redirects
After adding groups to scopes, Caddy security isn't working anymore with first "to many redirects" from OIDB and afterwards unauthorised. Groups are visible in the log.
A clear and concise description of what the issue is.
Configuration
Paste full Caddyfile
below:
{
http_port 8080
order authenticate before respond
order authorize before basicauth
security {
oauth identity provider generic {
realm generic
driver generic
client_id oauth2proxy
client_secret x
scopes openid email groups
base_auth_url https://oidb
metadata_url https://oidb
}
authentication portal myportal {
crypto default token lifetime 3600
crypto key sign-verify {env.JWT_SHARED_KEY}
enable identity provider generic
cookie insecure on
ui {
links {
"My Identity" "/whoami" icon "las la-user"
}
}
transform user {
match realm generic
match role antora
action add role authp/user
}
}
authorization policy mypolicy {
set auth url http://auth.site.example:3080/oauth2/generic/authorization-code-callback
crypto key verify {env.JWT_SHARED_KEY}
allow roles authp/admin authp/user
validate bearer header
inject headers with claims
}
}
}
http://auth.site.example {
authenticate with myportal
}
http://antora.site.example {
authorize with mypolicy
root * /usr/share/caddy
file_server
}
Version Information
Provide output of caddy list-modules -versions | grep git
below:
dmin.api.load v2.5.2
admin.api.metrics v2.5.2
admin.api.pki v2.5.2
admin.api.reverse_proxy v2.5.2
caddy.adapters.caddyfile v2.5.2
caddy.config_loaders.http v2.5.2
caddy.listeners.http_redirect v2.5.2
caddy.listeners.tls v2.5.2
caddy.logging.encoders.console v2.5.2
caddy.logging.encoders.filter v2.5.2
caddy.logging.encoders.filter.cookie v2.5.2
caddy.logging.encoders.filter.delete v2.5.2
caddy.logging.encoders.filter.hash v2.5.2
caddy.logging.encoders.filter.ip_mask v2.5.2
caddy.logging.encoders.filter.query v2.5.2
caddy.logging.encoders.filter.regexp v2.5.2
caddy.logging.encoders.filter.rename v2.5.2
caddy.logging.encoders.filter.replace v2.5.2
caddy.logging.encoders.json v2.5.2
caddy.logging.writers.discard v2.5.2
caddy.logging.writers.file v2.5.2
caddy.logging.writers.net v2.5.2
caddy.logging.writers.stderr v2.5.2
caddy.logging.writers.stdout v2.5.2
caddy.storage.file_system v2.5.2
http v2.5.2
http.authentication.hashes.bcrypt v2.5.2
http.authentication.hashes.scrypt v2.5.2
http.authentication.providers.http_basic v2.5.2
http.encoders.gzip v2.5.2
http.encoders.zstd v2.5.2
http.handlers.acme_server v2.5.2
http.handlers.authentication v2.5.2
http.handlers.copy_response v2.5.2
http.handlers.copy_response_headers v2.5.2
http.handlers.encode v2.5.2
http.handlers.error v2.5.2
http.handlers.file_server v2.5.2
http.handlers.headers v2.5.2
http.handlers.map v2.5.2
http.handlers.metrics v2.5.2
http.handlers.push v2.5.2
http.handlers.request_body v2.5.2
http.handlers.reverse_proxy v2.5.2
http.handlers.rewrite v2.5.2
http.handlers.static_response v2.5.2
http.handlers.subroute v2.5.2
http.handlers.templates v2.5.2
http.handlers.tracing v2.5.2
http.handlers.vars v2.5.2
http.matchers.expression v2.5.2
http.matchers.file v2.5.2
http.matchers.header v2.5.2
http.matchers.header_regexp v2.5.2
http.matchers.host v2.5.2
http.matchers.method v2.5.2
http.matchers.not v2.5.2
http.matchers.path v2.5.2
http.matchers.path_regexp v2.5.2
http.matchers.protocol v2.5.2
http.matchers.query v2.5.2
http.matchers.remote_ip v2.5.2
http.matchers.vars v2.5.2
http.matchers.vars_regexp v2.5.2
http.precompressed.br v2.5.2
http.precompressed.gzip v2.5.2
http.precompressed.zstd v2.5.2
http.reverse_proxy.selection_policies.cookie v2.5.2
http.reverse_proxy.selection_policies.first v2.5.2
http.reverse_proxy.selection_policies.header v2.5.2
http.reverse_proxy.selection_policies.ip_hash v2.5.2
http.reverse_proxy.selection_policies.least_conn v2.5.2
http.reverse_proxy.selection_policies.random v2.5.2
http.reverse_proxy.selection_policies.random_choose v2.5.2
http.reverse_proxy.selection_policies.round_robin v2.5.2
http.reverse_proxy.selection_policies.uri_hash v2.5.2
http.reverse_proxy.transport.fastcgi v2.5.2
http.reverse_proxy.transport.http v2.5.2
http.reverse_proxy.upstreams.a v2.5.2
http.reverse_proxy.upstreams.srv v2.5.2
pki v2.5.2
tls v2.5.2
tls.certificates.automate v2.5.2
tls.certificates.load_files v2.5.2
tls.certificates.load_folders v2.5.2
tls.certificates.load_pem v2.5.2
tls.certificates.load_storage v2.5.2
tls.client_auth.leaf v2.5.2
tls.get_certificate.http v2.5.2
tls.get_certificate.tailscale v2.5.2
tls.handshake_match.remote_ip v2.5.2
tls.handshake_match.sni v2.5.2
tls.issuance.acme v2.5.2
tls.issuance.internal v2.5.2
tls.issuance.zerossl v2.5.2
tls.stek.distributed v2.5.2
tls.stek.standard v2.5.2
Standard modules: 97
http.authentication.providers.authorizer v1.1.14
http.handlers.authenticator v1.1.14
http.handlers.trace v1.1.10
security v1.1.14
Non-standard modules: 4
Unknown modules: 0
Expected behavior
It's expected that groups can be verified with:
match role antora
Would love to release blog post about securing static sites with Caddy-Security soon. Would you have time to support me in fixing this issue?
@darox , please upgrade to 1.1.15 (latest). The issue may be fixed there. Please report back on your findings
Good morning
I have just updated to version 1.1.15. After adding groups to the configuration, the login isn't working anymore. See logs below.
oauth identity provider generic {
realm generic
driver generic
client_id oauth2proxy
client_secret x
scopes openid email groups
base_auth_url https://oidb
metadata_url https://oidb/.well-known/openid-configuration
}
Logs:
{"level":"info","ts":1661749878.4065108,"logger":"security","msg":"Successful login","session_id":"EuGs9Ytav6XqZdwMJuII9Jyl4z6P2Ix9WL7f6ct1qZ","request_id":"1f78dd33-438a-4bb0-8d12-b6d663771e21","backend":{"name":"generic","realm":"generic","method":"oauth"},"user":{"addr":"127.0.0.1","email":"[email protected]","exp":1661753478,"iat":1661749878,"iss":"http://auth.site.example:3080/oauth2/generic/","jti":"EuGs9Ytav6XqZdwMJuII9Jyl4z6P2Ix9WL7f6ct1qZ","nbf":1661749818000,"origin":"generic","realm":"generic","roles":["test","authp/user"],"sub":"CiRlM2I0M2Q2MS03OWUwLTQzZjgtOGE0OS01ZTI2NjQxM2VhY2MSBG9pZGI"}}
{"level":"debug","ts":1661749878.5255866,"logger":"security","msg":"Detected cookie-based redirect","session_id":"EuGs9Ytav6XqZdwMJuII9Jyl4z6P2Ix9WL7f6ct1qZ","request_id":"1f78dd33-438a-4bb0-8d12-b6d663771e21","redirect_url":"http://antora.site.example:3080/home/main/index.html"}
{"level":"debug","ts":1661749878.550247,"logger":"security","msg":"token validation error","session_id":"EuGs9Ytav6XqZdwMJuII9Jyl4z6P2Ix9WL7f6ct1qZ","request_id":"f2c81172-c563-475c-b782-41a471aa7ff5","error":"no token found"}
{"level":"debug","ts":1661749878.5506225,"logger":"security","msg":"redirecting unauthorized user","session_id":"EuGs9Ytav6XqZdwMJuII9Jyl4z6P2Ix9WL7f6ct1qZ","request_id":"f2c81172-c563-475c-b782-41a471aa7ff5","method":"location"}
{"level":"error","ts":1661749878.5508537,"logger":"http.handlers.authentication","msg":"auth provider returned error","provider":"authorizer","error":"user authorization failed: src_ip=127.0.0.1, src_conn_ip=127.0.0.1, reason: no token found"}
{"level":"debug","ts":1661749878.551244,"logger":"http.log.error","msg":"not authenticated","request":{"remote_ip":"127.0.0.1","remote_port":"45888","proto":"HTTP/1.1","method":"GET","host":"antora.site.example:3080","uri":"/home/main/index.html","headers":{"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"Referer":["http://antora.site.example:3080/"],"Cookie":[],"Connection":["keep-alive"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"],"Accept-Encoding":["gzip, deflate"],"Accept-Language":["de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"],"Cache-Control":["max-age=0"],"Upgrade-Insecure-Requests":["1"]}},"duration":0.001085875,"status":401,"err_id":"b3dbwi57k","err_trace":"caddyauth.Authentication.ServeHTTP (caddyauth.go:88)"}
{"level":"debug","ts":1661749878.5514545,"logger":"http.stdlib","msg":"http: superfluous response.WriteHeader call from github.com/caddyserver/caddy/v2/modules/caddyhttp.(*Server).ServeHTTP (server.go:286)"}
{"level":"debug","ts":1661749878.5677576,"logger":"security","msg":"redirect recorded","session_id":"EuGs9Ytav6XqZdwMJuII9Jyl4z6P2Ix9WL7f6ct1qZ","request_id":"7ca8aaf0-0b6a-4671-9b56-bbac595a13a8","redirect_url":"AUTHP_REDIRECT_URL=http://antora.site.example:3080/home/main/index.html; Domain=site.example; Path=/;"}
{"level":"debug","ts":1661749878.5678654,"logger":"security","msg":"External login requested","session_id":"EuGs9Ytav6XqZdwMJuII9Jyl4z6P2Ix9WL7f6ct1qZ","request_id":"7ca8aaf0-0b6a-4671-9b56-bbac595a13a8","base_url":"http://auth.site.example:3080","base_path":"/","auth_method":"oauth2","auth_realm":"generic","request_path":"/oauth2/generic"}
{"level":"debug","ts":1661749878.5680022,"logger":"security","msg":"redirecting to OAuth 2.0 endpoint","request_id":"7ca8aaf0-0b6a-4671-9b56-bbac595a13a8","redirect_url":"https://oidb/auth?client_id=oauth2proxy&nonce=3cfgNUulUQ3ljNUM7xwMwqpXpqFCJqxd&redirect_uri=http%3A%2F%2Fauth.site.example%3A3080%2Foauth2%2Fgeneric%2Fauthorization-code-callback&response_type=code&scope=openid+email+groups&state=830aa347-d6fc-4529-8834-e945b98074f8"}
{"level":"debug","ts":1661749878.568098,"logger":"security","msg":"Redirect to authorization server","session_id":"EuGs9Ytav6XqZdwMJuII9Jyl4z6P2Ix9WL7f6ct1qZ","request_id":"7ca8aaf0-0b6a-4671-9b56-bbac595a13a8","url":"https://oidb/auth?client_id=oauth2proxy&nonce=3cfgNUulUQ3ljNUM7xwMwqpXpqFCJqxd&redirect_uri=http%3A%2F%2Fauth.site.example%3A3080%2Foauth2%2Fgeneric%2Fauthorization-code-callback&response_type=code&scope=openid+email+groups&state=830aa347-d6fc-4529-8834-e945b98074f8"}
Thank you
@darox , does it work without “groups”?
@darox , please add “cookie domain site.example“ to auth portal config.
@greenpau Thank you for supporting me. Just donated 10$ to you.
I have tried with
cookie domain *.site.example
and
cookie domain site.example
Both are not working as soon I add "groups" to scopes. It ends in a to many redirects and unauthorized in Caddy-Security.
I don't really understand the difference when "groups" is added, except that it is requested from the identity provider. Shouldn't it make no difference as long the following config makes use of "match email" rather than "match roles test"?
transform user {
match realm generic
match email [email protected]
action add role authp/user
}
Side note: when I set cookie domain site.example
no cookie is set at all. When cookie domain *.site.example
is set, I can see the cookie in the chrome dev tools.
@darox , the issue is likely that you oauth provider does not allow your use of the “group” scope and therefore rejects it. Here are some of the possibilities.
- it could be that the authorization granted initially with oauth scopes are limited to say email only. In that case you could reauthorize.
- the “group” scope is not supported by your oauth provider
@darox , the issue is likely that you oauth provider does not allow your use of the “group” scope and therefore rejects it. Here are some of the possibilities.
it could be that the authorization granted initially with oauth scopes are limited to say email only. In that case you could reauthorize.
the “group” scope is not supported by your oauth provider
It's definitely supported. I can see the groups in the logs. With Oauth2-proxy I got it up and running.
@darox , what is your timezone? We could hop on Google Meet and try looking at it closer.
@darox , what is your timezone? We could hop on Google Meet and try looking at it closer.
GMT+2 sure
@darox , i am est (ny). Please let me know a few timeslots for tomorrow via email greenpau at outlook.com