Login to Keycloak that is behind Spring Cloud Api Gateway - spring-cloud

I have Keycloak and one Microservice running behind Spring Cloud API Gateway. I want to allow a client application to perform a /login HTTP request to let users login with their user name and password.
Because the client application will use the Password Grant Type, to authenticate with Keycloak via REST API, it will send HTTP Post request to a Keycloak /token endpoint
http://localhost:8080/auth/realms/<realm>/protocol/openid-connect/token
I want this request to go via Spring Cloud API Gateway. So I have configured a route but for some reason, I get 404 Not Found error even though the Keycloak is running and the endpoint is correct. Sending HTTP Post request to the above endpoint directly, without going through API gateway, works. I wonder why do I get a 404 error?
Below is my Spring Cloud API Gateway route configuration:
server.port=8085
spring.application.name=my-gateway-service
spring.security.oauth2.client.provider.custom.issuer-uri = http://localhost:8080/auth/realms/myrealm
spring.security.oauth2.client.provider.custom.user-name-attribute = preferred_username
spring.security.oauth2.client.provider.custom2.user-info-uri = http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/userinfo
spring.security.oauth2.client.registration.custom.client-name=my-spring-cloud-api-gateway
spring.security.oauth2.client.registration.custom.client-id = my-spring-cloud-api-gateway
spring.security.oauth2.client.registration.custom.client-secret = 3c832be7-2950-4490-801e-276b874d3dd3
spring.security.oauth2.client.registration.custom.scope = profile, openid, roles
spring.security.oauth2.client.registration.custom.authorization-grant-type = password
spring.cloud.gateway.routes[0].id = token-service
spring.cloud.gateway.routes[0].uri = http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
spring.cloud.gateway.routes[0].predicates[0]=Path=/token-service
spring.cloud.gateway.routes[0].predicates[1]=Method=POST
If I send HTTP Post request via API Gateway, I will get 404 Not found error.
curl --location --request POST 'http://localhost:8085/token-service' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=username' \
--data-urlencode 'password=mypassword' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=my-spring-cloud-api-gateway' \
--data-urlencode 'client_secret=3c832be7-2950-4490-801e-276b874d3dd3'
If I configure Spring Cloud API Gateway to route this HTTP Post request to another Microservice running on the localhost, then everything works. If I do not use API Gateway and send the above HTTP Post request directly to Keycloak endpoint http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token, then I get an access token. So Keycloak is running and the OAuth client application is configured to work with Password grant.
The 404 error code takes place only if send the above request via API Gateway and make the Gateway route the request to Keycloak endpoint http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
What do I do wrong?
Thank you!

I use the SetPath filter:
spring.cloud.gateway.routes[0].id=authToken
spring.cloud.gateway.routes[0].uri=http://localhost:8080
spring.cloud.gateway.routes[0].predicates[0]=Path=/auth/token
spring.cloud.gateway.routes[0].predicates[0]=Method=POST
spring.cloud.gateway.routes[0].filters[0]=SetPath=/auth/realms/myrealm/protocol/openid-connect/token

Related

Springboot app protected by keycloak return 403 after deploying in kubernates

I deploped the springboot app protected by Keycloak and it's working fine in localhost,but not working after deploying in kubernates, all the api return 403.
And the user has the resource permission when i use envaluate function in keycloak admin console(it definately has since it works well in localhost).
When i disable the authorization config(enforcement-mode=disable),all the api return 401.
Can anyone give some advice? Thanks in advance!!
The springboot config is like this:
enter image description here
After deploying the app in kubernates, i accessed the pod directly using curl and all the api return 403. The curl result is like this:curl -v --location --request GET 'http://10.42.4.224:80/menu/getRouters' --header 'Authorization: Bearer xxxxxxxx'
enter image description here
I access the api directly with token,but still return 403.
I disabled the authorization config by setting enforcement-mode=DISABLED,and access the api with token, the api return 401.

How do I set up a Google Cloud Function with Authentication?

Disclaimer: I'm completely new to Google Cloud Functions and serverless functions in general.
I've set up a basic Google Cloud Function, set it to HTTPS trigger and Require Authentication, and given the service account and my account the cloud function invoker role.
However, whenever I use Postman to sent an HTTP request to the function using my oauth2 token, I get a 401 Unauthorized error.
I've also followed the steps here: https://cloud.google.com/functions/docs/securing/authenticating
to create and download the service account key and make an HTTP request using cURL and get the same error.
How do I need to set this up so that authorized users can send HTTP requests to this function?
Here's what I'm doing:
$gcloud auth login (to log in with my account with cloud invoker permission)
$curl https://my-trigger-url \ -H "Authorization: bearer $(gcloud auth print-identity-token)"
Guillaume found the solution:
My cURL syntax to trigger the Cloud Function needed the -H "Authorization: bearer $(gcloud auth print-identity-token)" before the URL instead of after, which is the opposite of Google's own documentation.
Thanks for your help.

How to obtain the authorization code required for User Credentials through the cURL's command line

I trying to use GCS "User Credentials" to connect to Google cloud storage using libcurl library.
"User Credentials" authentication needs Client Id & Secret key to connect to GCS, but in this process Authentication Code also needs to be generated.
I need to generate this Authentication code using cURL.
Can anyone help me ??
The Client ID you mentioned is the same as the Authentication ID and can only be generated from either the Cloud Console's Credentials Page or via the OAuth 2.0 Playground.
If you are trying to generate an Access Token (OAUTH2_TOKEN), you will need to complete an authentication flow to authorize requests as a user. Cloud Storage uses OAuth 2.0 for API authentication and authorization.
Here's what you need to do to get an authorization access token from the OAuth 2.0 Playground:
Select & authorize APIs (Cloud Storage)
Select the scope for the APIs you would like to access or input your own OAuth scopes, e.g.: https://www.googleapis.com/auth/devstorage.read_write
Then click the "Authorize APIs" button
Once you've got the Authorization Code click the "Exchange authorization code for tokens" button, you will get a refresh and an access token which is required to access OAuth protected resources.
Grab the Access Token to use in your cURL command
Then configure your request to Cloud Storage API by constructing your HTTP request like so (upload):
curl -X POST --data-binary #[OBJECT_LOCATION] \
-H "Authorization: Bearer [OAUTH2_TOKEN]" \
-H "Content-Type: [OBJECT_CONTENT_TYPE]" \
"https://www.googleapis.com/upload/storage/v1/b/[BUCKET_NAME]/o?uploadType=media&name=[OBJECT_NAME]"
You can have a look at this Cloud Storage upload example in our public docs to guide you with constructing a request and testing it out.
Hope this helps.

How to Create Bluemix Secure Gateway from rest api

I am following this doc for reference.
I am able to get information for secure gateway, which is already created. But when I am trying to create a new secure gateway from the REST API, it is asking for authentication. I have tried to provide the authentication information two ways:
I have provided the oauth authorization header obtained from the cf oauth-token, but it gives me an unauthorized error.
I have given basic authentication (username and password of the Bluemix account) information, but it gives me an unauthorized error.
Note: I am using postman for this operation
Postman details:
url: https://sgmanager.au-syd.bluemix.net/v1/sgconfig?org_id=girishxxxxxxx#gmail.com&space_id=Equxxxxx
It is also saying "Invalid org_id", but the org_id is valid.
To create a gateway via the SG API, your request will need the query parameters ord_id and space_id (the guids, not the friendly names). The authorization header will be Basic <your_base64_encoded_username:password> or Bearer <bluemix_token>. For example:
curl "https://sgmanager.au-syd.bluemix.net/v1/sgconfig?org_id=myOrgGuid&space_id=mySpaceGuid" -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" -d '{"desc":"My Gateway"}'

How to authenticate against Kubernetes clusters running on Google Container Engine using REST API?

I'm writing an application to monitor a kubernetes cluster running on Google Container Engine. On the host where my application deployed, there are no kubectl and gcloud CLI nor are they allowed to be installed. So I am trying to do everything through REST API.
For creating the cluster through REST, I can use GCE Rest API with bearer token retrieved from Google OAuth Playground. Something like:
curl -i -X GET -H "Accept: application/json" -H "Content-Type: application/json" -H "Content-Length: 0" -H "Authorization: Bearer $MyBearerToken https://container.googleapis.com/v1/projects/$PROJECT_ID/zones/$ZONE/serverconfig
I can also find Kubernetes REST API reference here. So my question is: How do I retrieve, say pod information, from my GCE Kubernetes cluster, using REST api and REST api only?
I tried with kubectl get pods --v=8, and it's using GET https://${Kubenetes_IP}/api/v1/namespaces/default/pods. But when I use the same api endpoint to curl with my GCE bearer. It gives me Unzuthorized error message.
# curl --insecure -H "Authorization: Bearer $MyBearerToken" https://${Kubenetes_IP}/api/v1/namespaces/default/pods
Unauthorized
I am guessing because I need to use a different bearer token, or some other authentication method. I am wondering if anyone got a quick programtic one-liner? (Without resorting to kubectl or gcloud)
Reference
This answer affirms that there is a way using bearer token, but didn't give a pointer or example
This answer also seems promising, but all the link provided are broken (and api are deprecated as well)
This answer assumes kubectl and gcloud are installed, which is not allowed in my current use case.
Token can be retrieve from Google OAuth Playground
Kubernetes can be reached by the following curl command via REST API
# curl --insecure -H "Authorization: Bearer $MyBearerToken" https://${Kubenetes_IP}/api/v1/namespaces/default/pods
Kubernetes Master IP can be retrieved with kubectl get pods --v=8 and it could probably be retrieved somewhere from GCE Web GUI as well.
Full Kubernetes REST API can be found here
Make sure the token has not yet expired, and I think right now the default TTL is 1 hour.
When you authorize the OAuth2 playground to give you a token, it exchanges an Authorization Code for a Refresh Token and an Access Token.
The Access Token (from the OAuth2 playground) is valid for 1 hour.
The Refresh Token is a long-lived credential that is used to obtain new Access Tokens from the Authorization Server.
If you try to authenticate to the "Resource Owner" (in this case, Kubernetes) with an expired access token, it will respond with an HTTP 401 error.