greenpau / caddy-security

๐Ÿ” Authentication, Authorization, and Accounting (AAA) App and Plugin for Caddy v2. ๐Ÿ’Ž Implements Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0 (Github, Google, Facebook, Okta, etc.), SAML Authentication. MFA/2FA with App Authenticators and Yubico. ๐Ÿ’Ž Authorization with JWT/PASETO tokens. ๐Ÿ”
https://authcrunch.com/
Apache License 2.0
1.39k stars 70 forks source link

feature: enable CLI access to portal for non-local identities #243

Open jb-home opened 1 year ago

jb-home commented 1 year ago

I would like to access the server behind caddy-security with a powershell script.

I setup the authroization portal like described in: https://authp.github.io/docs/authenticate/oauth/backend-oauth2-0011-keycloak And using the browser everything works fine.

I am able to authenticate to keycloak and I am getting a valid token from the same client that is used by caddy-security.

The variable $token.access_token has a valid keycloak token from the same keycloak client. $local:header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $local:header.Add("Accept", "application/json") $local:header.Add("Content-Type", "application/json") $local:header.Add("Authorization", "Bearer $($token.access_token)")

$local:body = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $local:body.Add("Authorization", "Bearer $($token.access_token)")

$local:result = Invoke-WebRequest -Method Post -Uri "https://auth.example.com/login" -Headers $local:header -SkipHttpErrorCheck -Body $local:body $local:result

I am trying the approach you suggested here: https://authp.github.io/docs/authenticate/misc#json-api Caddy Log shows: "keystore: failed to parse token"

Any hint how I can get this to work?

greenpau commented 1 year ago

@jb-home , do you have bearer token support enabled in caddy security config? https://authp.github.io/docs/authorize/token-discovery

jb-home commented 1 year ago

I tried:

'validate bearer header' and 'set token sources header query cookie' and both at the same time.

I saw that the token I get from Keycloak has a different ALG. I think it is RS256, and auth.example.com has a HS512. So I set HS512 in the Keycloak client as default. Even than the token does not get accepted.

Do I have to set the same crypto-key? If so, do you know how to request a token with specific crypto-key?

greenpau commented 1 year ago

@jb-home , please share your config.

jb-home commented 1 year ago

Here my Caddyfile

{ order authenticate before respond order authorize before basicauth

security {
    oauth identity provider keycloak {
        driver generic
        realm keycloak
        client_id lpauthp
        client_secret <CLIENTSECRET>
        scopes openid email profile
        metadata_url https://keycloak.example.com/realms/MYREALM/.well-known/openid-configuration
    }

    authentication portal myportal {
        crypto default token lifetime 28800
        crypto key sign-verify <MYSIGNVERIFYKEY>
        enable identity provider keycloak
        cookie domain something.example.com
        ui {
            links {
                "My Identity" "/whoami" icon "las la-user"
            }
        }
    }

    authorization policy workflowpolicy {
        set token sources header query cookie
        validate bearer header
        set auth url https://auth.example.com/
        allow roles workflow/user
        crypto key verify <MYSIGNVERIFYKEY>
    }
}

grace_period 5s

}

(headers) { header { -Server Permissions-Policy interest-cohort=() X-Xss-Protection "1; mode=block" X-Robots-Tag none X-Frame-Options SAMEORIGIN Cache-Control no-cache Referer-Policy no-referer-when-downgrade X-Content-Type-Options nosniff Strict-Transport-Security "max-age=31536000; includeSubDomains" Content-Security-Policy upgrade-insecure-requests } }

:80 { redir / https://{hostonly}{uri} 301 }

auth.example.com { import headers authenticate with myportal }

workflows.example.com { import headers authorize with workflowpolicy reverse_proxy http://nodered:1880 { lb_policy ip_hash } }

greenpau commented 1 year ago

@jb-home , are you using HTTPS or HTTP? If it is 80, then secure cookies are not propagated. In that case, you have to use โ€œcookie insecure onโ€ directive.

greenpau commented 1 year ago

Also, I am not sure what effect the headers have on the cookies.

jb-home commented 1 year ago

I am using HTTPS only. The headers work fine using a browser. So I expect that CLI should be kind of transparent for the service.

greenpau commented 1 year ago

@jb-home , the cli login works only with local auth store. It would not work with OAuth user store.

jb-home commented 1 year ago

Is there a way you could make it work? As I pass the valid token from OAuth with same realm and same client, your plug-in should be able to verify that token. I wonder that nobody else is using such a construct.

greenpau commented 1 year ago

As I pass the valid token from OAuth with same realm and same client, your plug-in should be able to verify that token. I wonder that nobody else is using such a construct.

There is, but it requires development time.

What needs to happen is connecting the identities from various store and linking them to local store. See https://github.com/greenpau/caddy-security/issues/23