How to authenticate to oauth2-proxy via cURL or POSTMAN - oauth-2.0

I have my service set behind oauth2-proxy and I am using version 4.0.0.
I am trying to hit an API behind the service, but unfortunately, I always get a 403 forbidden error because of oauth2-proxy being in the way.
I am looking for a way to authenticate via g-suite using oauth2-proxy and generate a token that I can then use for the service.
Does oauth2-proxy support any kind of way to authenticate via cURL or POST call?

Related

How to configure keycloak with krakend to access apache2 webserver?

I'm struggling with krakend and keycloak. I have the following:
Apache2 Webserver with a my-ip/keycloak-protected file (directly on the host)
Krakend with my-ip:8402 (as a docker container)
Keycloak with my-ip:8080 (as a docker container)
I want to protect the keycloak-protected file, so only logged in users can access it. For krakend I use this config: https://www.krakend.io/docs/authorization/keycloak/. I changed it to match my IP:
{"version": 3,
"timeout": "3s",
"endpoints":[{"endpoint": "/keycloak-protected",
"extra_config": {"auth/validator": {"alg": "RS256",
"jwk_url": "http://<my-ip>:8080/auth/realms/master/protocol/openid-connect/certs",
"disable_jwk_security": true}},
"backend": [{"host":["http://<my-ip>:80"],
"url_pattern": "/__health"}]}]}
I then set up keycloak, create a client with valid redirect URLs = http://my-ip:8402/* and access type Public. I also create a new user.
Using postman, I try to access http://my-ip:8402/keycloak-protected with a GET. I fill out the parameters in the tab Authorization and click "Get new access token", where I successfully log in and get a (valid?) token. But when I then try to access http://my-ip:8402/keycloak-protected, it says 401 Unauthorized.
What am I missing here? Am I using postman wrong? Is the krakend config faulty? Or is the keycloak client not configured properly?
Thank you very much!
I followed the tutorials https://www.krakend.io/docs/authorization/keycloak/ and some parts of https://github.com/xyder/example-krakend-keycloak.
I would like to have different realms/clients/users to only access specific files on my apache2 webserver.
I found the solution: The example on the krakend website (on https://www.krakend.io/docs/authorization/keycloak/) is faulty. The URL in the jwk_url should be:
http://:8080/realms/master/protocol/openid-connect/certs
and NOT:
http://:8080/auth/realms/master/protocol/openid-connect/certs
(see the missing /auth in the URL).

Oauth2_proxy with Keycloak : getting "invalid_token" with /userinfo API

I am trying Keycloak for the first time and using Keycoak as provider with oauth2_proxy (https://github.com/oauth2-proxy/oauth2-proxy/blob/v5.1.1/providers/keycloak.go) to achieve user authentication via LDAP.
I have followed all steps inside Keycloak to create a realm, create client, client id, client secret etc. Also the Keycloak API "/token" is passing. However once I pass username/password in the keycloak login screen, I get following error in oauth2_proxy:
[2020/05/30 10:15:37] [requests.go:25] 401 GET http://172.20.0.10:8080/auth/realms/master/protocol/openid-connect/userinfo {"error":"invalid_token","error_description":"Token verification failed"}
Also I am passing following parameters when bringing up oauth2_proxy docker container:
command: -upstream=static://200 -http-address=0.0.0.0:8080 -https-address=0.0.0.0:8443
-redirect-url="https://portal.acme.com/oauth2/callback"
-scope='test-scope' -email-domain=* -cookie-domain=* -cookie-secure=false -cookie-secret=skjgfsgfsf23524
-cookie-samesite="none" -provider=keycloak
-client-id='abcd-client' -client-secret='c0281257-b600-40b2-beae-68d1f2d72f02'
--tls-cert-file=/etc/acme.com.pem
--tls-key-file=/etc/acme.com.key
-login-url="http://localhost:7575/auth/realms/master/protocol/openid-connect/auth"
-redeem-url="http://172.20.0.10:8080/auth/realms/master/protocol/openid-connect/token"
-validate-url="http://172.20.0.10:8080/auth/realms/master/protocol/openid-connect/userinfo"
Can someone please help what could be missing or going wrong?
Any lead or hint will be really helpful.
I found the solution to this problem. This was because the issuer in the JWT token was not matching with the URL I gave when bringing up this oauth2_proxy container.
To fix this, what was needed is that the docker container needed to talk to the host network and port exposed by Keycloak. This needs 2 things:
Use "host.docker.internal" as host in all Keycloak APIs when bringing up oauth2_proxy so that oauth2_proxy container communicates Keycloak via host network.
Map "host.docker.internal" to 127.0.0.1 in local machine/host so that the browser redirect is accessible.
After this little hack, the setup works.
Thanks!

keycloak token introspection always fails with {"active":false}

I'm kind of desesperate to make this keycloak work. I can authenticate but for some reason, my token introspection always fail.
For example if I try to authenticate:
curl -d 'client_id=flask_api' -d 'client_secret=98594477-af85-48d8-9d95-f3aa954e5492' -d 'username=jean#gmail.com' -d 'password=superpassE0' -d 'grant_type=password' 'http://keycloak.dev.local:9000/auth/realms/skilltrock/protocol/openid-connect/token'
I get my access_token as expected:
{
"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJnLVZJQ0VETnJ4NWRfN1pWQllCTC1tNDdTZWFNT3NDVlowSFdtZF9QQkZrIn0.eyJqdGkiOiIwNTBkYWI5MS1kMjA5LTQwYjctOTBkOS1mYTgzMWYyMTk1Y2MiLCJleHAiOjE1NDQ1MjIyNDEsIm5iZiI6MCwiaWF0IjoxNTQ0NTIxOTQxLCJpc3MiOiJodHRwOi8va2V5Y2xvYWsuZGV2LmxvY2FsOjkwMDAvYXV0aC9yZWFsbXMvc2tpbGx0cm9jayIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI3NDA0MWNkNS1lZDBhLTQzMmYtYTU3OC0wYzhhMTIxZTdmZTAiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJmbGFza19hcGkiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJiOGI0MzA2Ny1lNzllLTQxZmItYmNkYi0xMThiMTU2OWU3ZDEiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJqZWFuIHBpZXJyZSIsInByZWZlcnJlZF91c2VybmFtZSI6ImplYW5AZ21haWwuY29tIiwiZ2l2ZW5fbmFtZSI6ImplYW4iLCJmYW1pbHlfbmFtZSI6InBpZXJyZSIsImVtYWlsIjoiamVhbkBnbWFpbC5jb20ifQ.x1jW1cTSWSXN5DsXT3zk1ra4-BcxgjXbbqV5cjdwKTovoNQn7LG0Y_kR8-8Pe8MvFe7UNmqrHbHh21wgZy1JJFYSnnPKhzQaiT5YTcXCRybSdgXAjnvLpBjVQGVbMse_obzjjE1yTdROrZOdf9ARBx6EBr3teH1bHMu32a5wDf-fpYYmHskpW-YoQZljzNyL353K3bmWMlWSGzXx1y7p8_T_1WLwPMPr6XJdeZ5kW0hwLcaJVyDhX_92CFSHZaHQvI8P095D4BKLrI8iJaulnhsb4WqnkUyjOvDJBqrGxPvVqJxC4C1NXKA4ahk35tk5Pz8uS33HY6BkcRKw7z6xuA",
"expires_in":300,
"refresh_expires_in":1800,
"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlYmY4ZDVlOC01MTM4LTRiNTUtYmZhNC02YzcwMzBkMTIwM2YifQ.eyJqdGkiOiI3NWQ1ODgyMS01NzJkLTQ1NDgtOWQwYS0wM2Q3MGViYWE4NGEiLCJleHAiOjE1NDQ1MjM3NDEsIm5iZiI6MCwiaWF0IjoxNTQ0NTIxOTQxLCJpc3MiOiJodHRwOi8va2V5Y2xvYWsuZGV2LmxvY2FsOjkwMDAvYXV0aC9yZWFsbXMvc2tpbGx0cm9jayIsImF1ZCI6Imh0dHA6Ly9rZXljbG9hay5kZXYubG9jYWw6OTAwMC9hdXRoL3JlYWxtcy9za2lsbHRyb2NrIiwic3ViIjoiNzQwNDFjZDUtZWQwYS00MzJmLWE1NzgtMGM4YTEyMWU3ZmUwIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImZsYXNrX2FwaSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6ImI4YjQzMDY3LWU3OWUtNDFmYi1iY2RiLTExOGIxNTY5ZTdkMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIn0.omhube2oe79dXlcChOD9AFRdUep53kKPjD0HF14QioY",
"token_type":"bearer",
"not-before-policy":0,
"session_state":"b8b43067-e79e-41fb-bcdb-118b1569e7d1",
"scope":"email profile"
}
But if I try to introspect the access_token like given below, keycloack return always {"active":false}. I really don't understand this behavior.
curl -X POST -u "flask_api:98594477-af85-48d8-9d95-f3aa954e5492" -d "token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJnLVZJQ0VETnJ4NWRfN1pWQllCTC1tNDdTZWFNT3NDVlowSFdtZF9QQkZrIn0.eyJqdGkiOiIwNTBkYWI5MS1kMjA5LTQwYjctOTBkOS1mYTgzMWYyMTk1Y2MiLCJleHAiOjE1NDQ1MjIyNDEsIm5iZiI6MCwiaWF0IjoxNTQ0NTIxOTQxLCJpc3MiOiJodHRwOi8va2V5Y2xvYWsuZGV2LmxvY2FsOjkwMDAvYXV0aC9yZWFsbXMvc2tpbGx0cm9jayIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI3NDA0MWNkNS1lZDBhLTQzMmYtYTU3OC0wYzhhMTIxZTdmZTAiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJmbGFza19hcGkiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJiOGI0MzA2Ny1lNzllLTQxZmItYmNkYi0xMThiMTU2OWU3ZDEiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJqZWFuIHBpZXJyZSIsInByZWZlcnJlZF91c2VybmFtZSI6ImplYW5AZ21haWwuY29tIiwiZ2l2ZW5fbmFtZSI6ImplYW4iLCJmYW1pbHlfbmFtZSI6InBpZXJyZSIsImVtYWlsIjoiamVhbkBnbWFpbC5jb20ifQ.x1jW1cTSWSXN5DsXT3zk1ra4-BcxgjXbbqV5cjdwKTovoNQn7LG0Y_kR8-8Pe8MvFe7UNmqrHbHh21wgZy1JJFYSnnPKhzQaiT5YTcXCRybSdgXAjnvLpBjVQGVbMse_obzjjE1yTdROrZOdf9ARBx6EBr3teH1bHMu32a5wDf-fpYYmHskpW-YoQZljzNyL353K3bmWMlWSGzXx1y7p8_T_1WLwPMPr6XJdeZ5kW0hwLcaJVyDhX_92CFSHZaHQvI8P095D4BKLrI8iJaulnhsb4WqnkUyjOvDJBqrGxPvVqJxC4C1NXKA4ahk35tk5Pz8uS33HY6BkcRKw7z6xuA" http://localhost:9000/auth/realms/skilltrock/protocol/openid-connect/token/introspect
return
{"active":false}
Where I am wrong? I'm totally lost
You need to make sure that you introspect the token using the same DNS hostname/port as the request. Unfortunately that's a not widely documented "feature" of Keycloak...
So use:
curl -u "flask_api:98594477-af85-48d8-9d95-f3aa954e5492" -d "token=<token>" http://keycloak.dev.local:9000/auth/realms/skilltrock/protocol/openid-connect/token/introspect
A legacy alternative is to send a Host header with the introspection request which matches the frontend host where the token was obtained. That I have tried, I can confirm that it works. It requires configuration of two URLs for the introspecting protected resource, though.
Since Keycloak 8 it is also possible to use the OpenID Connect Discovery as described in https://issues.redhat.com/browse/KEYCLOAK-11728 and the attached design document.
The latter solution involves two things:
Keycloak needs to know the frontend URL used for token retrieval by clients; that can happen at start time as described in the server installation (-Dkeycloak.frontendUrl or standalone.xml) or when definining a realm through its Frontend URL Option in the Keycloak Management UI. The Keycloak docker container supports the environment variable KEYCLOAK_FRONTEND_URL for this. Note that the frontendUrl needs to include the basePath where Keycloak is running (/auth by default, adjust as needed).
Optionally, the protected resource can use OIDC discovery to determine the introspection URL. Either use the Keycloak Java Adapter >=v8 which has built-in support for OIDC Discovery or verify if your protected resource does. See the related PR on the Keycloak Java Adapter for details.
When a protected resource uses the internal discovery endpoint http://keycloak:8998/auth/realms/myrealm/.well-known/openid-configuration, it will find the correct internal introspection endpoint:
{
"issuer": "http://localhost:8998/auth/realms/myrealm",
"authorization_endpoint": "http://localhost:8998/auth/realms/myrealm/protocol/openid-connect/auth",
"token_endpoint": "http://keycloak:8080/auth/realms/myrealm/protocol/openid-connect/token",
"token_introspection_endpoint": "http://keycloak:8080/auth/realms/myrealm/protocol/openid-connect/token/introspect"
}
Using the discovery endpoint is not required. If you just need to introspect an incoming token with Keycloak, you can directly use the introspection endpoint.
The introspect endpoint can also return {"active":false} if a session associated with that token doesn't exist in Keycloak. For example, if you create the token, restart keycloak and then call introspect.
As mentioned earlier the same domain should be used when obtaining and introspecting the token.
For me, I was using the localhost to obtain the token and 127.0.0.1 to introspect the token.

Introspection Endpoint of KeyCloak server

I am trying to explore features of KeyCloak server and want to get information about access token by using /openid-connect/token/introspect endpoint.
So, I am sending next request to this endpoint
curl -v --data "token_type_hint=access_token&client_id=product-
app&username=user&token=MY ACCESS TOKEN"
http://localhost:8080/auth/realms/springdemo/protocol/openid-
connect/token/introspect
So this is what I have as a response:
{"error":"invalid_request","error_description":"Client not allowed."}*
Connection #0 to host localhost left intact
and this is what I see in KeyCloak's logs:
12:00:18,045 WARN [org.keycloak.events] (default task-13)
type=INTROSPECT_TOKEN _ERROR,
realmId=springdemo, clientId=product-app, userId=null, ipAddress=127.0.0
.1, error=invalid_request, detail='Client not allowed.',
client_auth_method=client-secret
So, I can't get it - how should I properly make request to keycloak in this case regarding that product-app has public access. Please, explain!
It seems like you are not able to use /openid-connect/token/introspect endpoint when your client has public access type.
So, switch to the CONFIDENTIAL ACCESS TYPE and use
curl -v --data "client_secret=YOUR_SECRET9&client_id=product-
app&username=user&token=YOUR_TOKEN"
http://localhost:8080/auth/realms/springdemo/protocol/openid-
connect/token/introspect
It works fine.

Spring Netflix Zuul: Authenticate and Route the same request

I have a bunch of services that sit behind a Zuul Edge Server. The Zuul Edge Server also performs authentication. The session is shared with all services using Spring Session. I want to be able to authenticate and route the request to a service in the same flow. I looked at Dave Syer's tutorial where a Gateway Server can authenticate and route requests.
On that project, the following commands work:
curl -u admin:admin http://localhost:8080/user
curl -c cookie.txt -u admin:admin http://localhost:8080/user
&& curl -b cookie.txt http://localhost:8080/admin/user
I was expecting this to work as well but it doesn't:
curl -u admin:admin http://localhost:8080/admin/user
I was expecting the Gateway server to authenticate, create a redis session, route the request to admin service which would have picked the Authentication from redis session. The request is being routed to admin service, but it also attempts a Basic Authentication and fails.
This is what I see in admin service's logs:
o.s.s.w.a.www.BasicAuthenticationFilter : Basic Authentication Authorization header found for user 'admin'
o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
o.s.s.a.dao.DaoAuthenticationProvider : User 'admin' not found
o.s.s.w.a.www.BasicAuthenticationFilter : Authentication request for failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
I get an HTTP 401 Unauthorized response.
I also tried to disable HTTP Basic Authentication in admin service, but then I get HTTP 403 Forbidden response.
Is there some way to achieve this?
UPDATE
I think this can't work due to the way Spring Session is implemented to save session. I'm waiting for a response to my question on github.

Resources