Connection to KV Vault is only working through a WireMock - spring

If I'm trying to connect to my Vault Engine, I get a Error 503 Service Unavailable. If I'm sending the call to a local WireMock which redirects the call with less headers to the same address, it works. Spring Cloud Version is 3.1.1
Cannot enhance VaultToken to a LoginToken: Token self-lookup failed: 503 <html><body><h1>503 Service Unavailable</h1>
The bootstrap config looks like this
spring:
cloud:
vault:
scheme: https
host: <uri-to-the-vault>
port: 443
uri: <uri-to-the-vault>
authentication: token
token: "TOKEN"
enabled: true
kv:
enabled: true
backend: <backend-name>
profiles: <profile-name>
application-name: <application-name>
I tried to setup a connection through WireMock to look if the call is incorrect. I tried to redirect the call. Wiremock takes the call and sends it just to the same base url written above but only with the token as a header and it works. Postman takes the same call and it works aswell.

Related

Spring Cloud Gateway response never arrives using tls client

I encountered a problem with TSL/SSL configuration. Everything is configured like in the documentation https://cloud.spring.io/spring-cloud-gateway/multi/multi__tls_ssl.html
server:
port: 8080
ssl:
enabled: true
key-password: password
key-store-password: password
key-store: certificate.p12
key-store-type: PKCS12
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- someCert.pem
With this configuration it's impossible to call endpoint with tls, the responses never arrives. Instead,if I conf endpoints whithout tls, works.
I also use Eureka.
however the microservice is completing the call and 200 is returned from it, but the body is not received in my gateway..
Could you help me?
Thanks,

Keycloak: Invalid token issuer when running as docker service

I have a problem:
WWW-Authenticate Bearer realm="test", error="invalid_token", error_description="Invalid token issuer. Expected 'http://keycloak:8080/auth/realms/test', but was 'http://localhost:8080/auth/realms/test'"
My settings:
application.yml
keycloak:
realm: test
resource: api
auth-server-url: http://keycloak:8080/auth
ssl-required: external
autodetect-bearer-only: true
cors: true
principal-attribute: preferred_username
credentials:
secret: 2b553733-8d5f-4276-8ace-17112ac7ac20
docker-compose.yml
keycloak:
image: jboss/keycloak:10.0.0
environment:
- KEYCLOAK_USER=admin
- KEYCLOAK_PASSWORD=admin
ports:
- "8080:8080"
networks:
- net
Auth url: http://localhost:8080/auth/realms/test/protocol/openid-connect/auth
Token url: http://localhost:8080/auth/realms/test/protocol/openid-connect/token
I understand why the problem exists, but I don`t understand how to fix it.
Keycloak's Default Hostname Provider (https://www.keycloak.org/docs/latest/server_installation/#default-provider) has a property called frontendURL which should be set as the public URL on which Keycloak is exposed.
Setting frontendURL ensures that all front-channel URLs, like issuer, authorization_endpoint use the configured value as hostname in the URLs and back-channel URLs keep using hostname in the request.
I added 127.0.0.1 keycloak in hosts file and used http://keycloak:8080/auth/realms/*** url to get the token. Now the JWT token contained the issuer as keycloak instead of localhost. I verified the token using jwt.io website. This resolved the mismatch in token issuer.

Spring Cloud Gateway and TokenRelay Filter

I’m trying to migrate JHipster from using Zuul to Spring Cloud Gateway. JHipster uses Eureka to look up routes and I believe I’ve configured Spring Cloud Gateway correctly to look up routes and propagate the access token to them. Here’s my config:
spring:
cloud:
gateway:
default-filters:
- TokenRelay
discovery:
locator:
enabled: true
lower-case-service-id: true
route-id-prefix: /services/
httpclient:
pool:
max-connections: 1000
The problem I’m experiencing is the access token is not sending an Authorization header to the downstream services.
Here's how things were configured with Zuul in my application.yml:
zuul: # those values must be configured depending on the application specific needs
sensitive-headers: Cookie,Set-Cookie #see https://github.com/spring-cloud/spring-cloud-netflix/issues/3126
host:
max-total-connections: 1000
max-per-route-connections: 100
prefix: /services
semaphore:
max-semaphores: 500
I created a pull request to show what's changed after integrating Spring Cloud Gateway.
https://github.com/mraible/jhipster-reactive-microservices-oauth2/pull/4
Steps to reproduce the issue:
git clone -b reactive git#github.com:mraible/jhipster-reactive-microservices-oauth2.git
Start JHipster Registry, Keycloak, and the gateway app:
cd jhipster-reactive-microservices-oauth2/gateway
docker-compose -f src/main/docker/jhipster-registry.yml up -d
docker-compose -f src/main/docker/keycloak.yml up -d
./mvnw
Start MongoDB and the blog app:
cd ../blog
docker-compose -f src/main/docker/mongodb.yml up -d
./mvnw
Navigate to http://localhost:8080 in your browser, log in with admin/admin, and try to go to Entities > Blog. You will get a 403 access denied error. If you look in Chrome Developer Tools at the network traffic, you'll see the access token isn't included in any headers.
I was able to solve this using this answer.
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
predicates:
- name: Path
args:
pattern: "'/services/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/services/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
I also had to add .pathMatchers("/services/**").authenticated() to my security config, which wasn't needed for Zuul. You can see my commit here.

Adding authentication proxy in front of kubernetes

I'm adding a proxy in front of kubernetes API in order to authenticate users (among other actions) with a homemade authentication system.
I've modified my kube configuration to have kubectl hitting the proxy. The proxy has its own kubeconfig with a valid certificate-authority-data, so I don't need any credentials on my side.
So far this is working fine, here is the minimum configuration I need locally:
clusters:
- cluster:
server: http://localhost:8080
name: proxy
contexts:
- context:
cluster: proxy
name: proxy
current-context: proxy
Now the authentication should be based on a token, that I hoped I would be able to pass as part of the kubectl request header.
I tried multiple configuration, adding a user with a token in the kubeconfig such as
clusters:
- cluster:
server: http://localhost:8080
name: proxy
contexts:
- context:
cluster: proxy
user: robin
name: proxy
current-context: proxy
users:
- name: robin
user:
token: my-token
Or specifying a auth-provider such as
clusters:
- cluster:
server: http://localhost:8080
name: proxy
contexts:
- context:
cluster: proxy
user: robin
name: proxy
current-context: proxy
users:
- name: robin
user:
auth-provider:
config:
access-token: my-token
I even tried without any user, just by adding my token as part of the preferences, as all I want is to have the token in the header
clusters:
- cluster:
server: http://localhost:8080
name: proxy
contexts:
- context:
cluster: proxy
name: proxy
current-context: proxy
preferences:
token: my-token
But I was never able to see my-token as part of the request header on the proxy side. Dumping the request, all I got is:
GET /api/v1/namespaces/default/pods?limit=500 HTTP/1.1
Host: localhost:8080
Accept: application/json;as=Table;v=v1beta1;g=meta.k8s.io, application/json
Accept-Encoding: gzip
User-Agent: kubectl/v1.11.0 (darwin/amd64) kubernetes/91e7b4f
I am obviously missing something here, how can kubectl not pass the user information in its header? Let's say I do not have a proxy, how is the "kubectl -> kubernetes" token authentication working?
If someone has any experience at adding this kind of authentication layer between kubernetes and a client, I could use some help :)
Token credentials are only sent over TLS-secured connections. The server must be https://...

Spring Cloud Vault is not working with custom mount

In local machine, I ran Vault server with default policy and wrote the following key value.
vault write secret/my-application username=Test
bootstrap.yml (Working)
spring:
application:
name: my-application
cloud:
vault:
authentication: TOKEN
token: sometoken
host: localhost
port: 8200
scheme: http
#uri: http://localhost:8200
connection-timeout: 5000
read-timeout: 15000
config:
order: -10
I was able to fetch the value using Spring Cloud Vault i.e. when I use default mount (secret). But If I hit the QA server with the custom mount(group) I am getting the following error.
org.springframework.vault.VaultException: Status 403 secret/group/grouptype/groupname/DB: permission denied
(Not sure why secret is prefixed)
bootstrap.yml (Not working)
spring:
application:
name: group/grouptype/groupname/DB
cloud:
vault:
authentication: TOKEN
token: sometoken
host: 10.20.30.40
port: 8200
scheme: http
#uri: http://10.20.30.40:8200
connection-timeout: 5000
read-timeout: 15000
config:
order: -10
But if I hit the API from POSTMAN it is working as expected.
GET
http://10.20.30.40:8200/v1/group/grouptype/groupname/DB
Header:
X-Vault-Token:sometoken
How to make custom proxy work with Spring boot application. How to exclude secret from the context
For a custom mount, we have to add generic
spring:
application:
name: grouptype/groupname/DB
cloud:
vault:
authentication: TOKEN
token: sometoken
generic:
enabled: true
backend: group
default-conext: grouptype/groupname/DB
host: 10.20.30.40
port: 8200
scheme: http
#uri: http://10.20.30.40:8200
connection-timeout: 5000
read-timeout: 15000
config:
order: -10
Here "group" is the mount name

Resources