Swagger incorrect API path - spring-boot

I'm using swagger and swagger UI to document my APIs. This is in a spring boot microservice set up. I am consolidating all swagger docs into my zuul gateway. This all works fine for displaying the documentation.
However when you try and execute the APIs using the Try It Out button, this fails as the path being used to hit the endpoint is incorrect. Specifically swagger seems to expect the downstream service to have no context root. Is there anyway i can configure this to accept a context root?
I've reproduced the issue on this repo https://github.com/craigmgordon/swagger
If i run the services and hit the gateway on http://localhost:20000/swagger-ui.html i can see the docs for my two services are displayed correctly.
You can see the url is correct at the top of the page http://localhost:20000/prod/product/v2/api-docs
where 'prod' is the zuul route to the product-service
and 'product' is the product-service context route
If I try and use Try ITOut on the /products endpoint though, on execution i get a 404 as its tried to hit the url http://localhost:20000/prod/products
i.e. has ommitted the context route.
Correct url should be http://localhost:20000/prod/product/products
Has anyone had the same issue and found a resolution??

Related

SpringBoot GraphQL Not exposing /graphql endpoint

Currently trying to setup SpringBoot and GraphQL but whenever I run the application I don't seem to get the /graphql endpoint exposed, nor does the graphiql UI get exposed when I set it to enabled in the application.yml file.
I've also tried setting the endpoint manually in the properties but that also isn't exposed.
I've pushed up the code to github below as I can't work out where the problem would be.
https://github.com/RyanMoss96/spring-boot-graphql
graphql.servlet.mapping=/graphql
Add this information to application.yaml

CAMUNDA API REST Authentication

I am trying to connect from my javascript front to the REST API of my camunda orchestration which is deployed as part of a spring boot application.
the called url is :
GET http://localhost:8081/oms-orchestrator-ms/api/engine/engine/default/history/process-instance
i get an 401 error for non authenticated queries which is normal
First question : is it the right way to query the Engine Rest API for process definition/ instances and history?
In order to make it work , i add the JSESSIONID cookie as header to my requests,
how can i use the basic auth to query the orchestrator api instead of using the cookie?
Thanks for your Help
the /api path is part of the cockpits REST backend which is secured by the same rules as the cockpit webapp.
You can additionally deploy the rest api (camunda-bpm-spring-boot-starter-rest if you are using spring boot). This will add an almost identical REST api for the engine under the path /rest. This one is open by default and can be secured manually if required (and advised for prod environments).

API-first rest endpoint not listed in jhipster-gateway API section (swagger-ui)

Using jhipster 5.7.2
I created an api-gateway, and two micro-services.
In the first one, I created an entity and it works perfectly behind the gateway. The gateway displays the api endpoints for the generated entity.
I generated the second micro-service but this time I had already an api defined in a yml file so I chose 'API-first'.
My api was defined using open-api 3.
I successfully generated the code for my api, using the instructions there, and tested calling direcly my micro-service endpoint using curl : it worked as expected at this point.
The problem : when I put that micro-service behind the gateway, the gateway does not see the api. When I go to the api menu, my micro-service shows in the dropdown but when I select it, it shows no endpoints.
One weird thing I found while searching is that when I call the following url on my micro-service directly : http://localhost:8082/v2/api-docs (as pointed in the 'welcome page' of the micro-service), I get :
{"swagger":"2.0","info":{"description":"my micro-service API documentation","version":"0.0.1","title":"api-first micro-service API","contact":{},"license":{}},"host":"localhost:8082","basePath":"/"}
It says 'swagger 2.0' when my yml file declared openapi 3.0.1.
I searched and found this issue, which says :
Swagger UI very old version (2.2.10) is used which does not provide
the support for Open API
I though openapi was the problem, so I rewrote the yml file to swagger 2.0 and finally I have the same exact problem : micro-service API works but seems not visible to the gateway.
I'm starting to wonder if it's a problem on my side only.
By default, JHipster configures Swagger to only list API endpoints beginning with api. This is configured in application.yml, change default-include-pattern to include other paths. For example, to include endpoints beginning with either /api/ or /expires/, you can use the following:
swagger:
default-include-pattern: /(api|expires)/.*

Zuul proxy that discovers routes dynamically

I have a simple Zuul app that has a single route in the application.yml to route to my microservice. It's working.
However, what I'm looking for is a more dynamic solution where I can wire up routes dynamically, either through code or perhaps by POSTing to some Zuul endpoints during a build (possibly by using springfox and a swagger definition from microservices). I could not find an API for Zuul.
I'm somewhat aware of Eureka and that seems like a solution to abstract away the routing by doing discovery. However, I'm curious if there's a solution without introducing Eureka. If there's a way to wire up these routes in Zuul during a build vs. having to edit the application.yml every time.
Thanks in advance.
If you go for Eureka this will actually work ootb. Zuul as packaged in spring cloud will automatically expose every service using its name. So if you register a service called users in Eureka, Zuul will automatically create a route /users forwarding to the instances by default. That will only allow simple url structures but should solve your problem.
Please see the official documentation for details:
By convention, a service with the ID "users", will receive requests from the proxy located at /users (with the prefix stripped). The proxy uses Ribbon to locate an instance to forward to via discovery, and all requests are executed in a hystrix command, …
I'm actually editing a blog post about this exact topic (Routing and Filtering using Spring Cloud Zuul Server) but the source code has been available and working for some time now. Feel free to use it as a reference:
https://bitbucket.org/asimio/zuulserver
https://bitbucket.org/asimio/discoveryserver (in case routes are configured with serviceIds)
https://bitbucket.org/asimio/demo-config-properties/src (Zuul-Server-refreshable.yml where routes are dynamically updated).
Look at the refreshable Spring profile settings. This Zuul setup works with both, hard-coding routes url or discovered using Eureka.
It also acting as a Spring Cloud Config client so that routes could be dynamically updated via Git, which is also covered in another blog post: Refreshable Configuration using Spring Cloud Config Server, Spring Cloud Bus, RabbitMQ and Git.

How to integrate keycloak in Spring Boot with a different context root and reverse proxy

We are currently developing a microservice application using Spring Boot 1.4 and Keycloak 2.5.0 (configured as openid-connect service) using the Keycloak Spring Adapter (not the Spring Boot adapter).
All of our microservices are put behind a load balancer and an additional reverse proxy as the application will be hosted on an existing domain behind a context root (so the root of our application is http://foo.bar/foobar/ and the rest services are http://foo.bar/foobar/rest/).
We are facing a couple of problems with Keycloak in this given scenario:
Keycloak forward to /sso/login if a sign-in is needed. This is in our case unwanted behaviour because http://foo.bar/sso/login will not exist. I have found a way to change the forward but there is no way to make Keycloak listen to the same url; we end up with a 404 in this case.
After signing in, Keycloak redirects back to the /sso/login url with the correct tokens, but if this is not the same server, the request fails and it redirects us to http://foo.bar/. Since every microservice exposes /sso/login, this can be in fact a completely different server.
If keycloak is hosted on the same domain, we end up in a redirect loop. We would also like to have Keycloak hosted on the same domain and on the context root http://foo.bar/foobar/auth/ .
We've already tried using the "token-store": "cookie" but this did not resolve the problem.
Is there a way to resolve these problems or is Keycloak maybe not the correct solution for our use-case ?
Update 05/05/2017:
Move my answer from here to an answer
We are now up and running with Keycloak so I'll briefly explain what we did. The front-end of our application runs Angular2 and we created a custom login page in the Angular application itself (so it's not a theme for Keycloak) which will directly query the Keycloak API for an OAuth2 Bearer token. The front-end will send this token on each request in the Authorization header (as per the OAuth standards).
On the service side we have configured keycloak as a bearer-only solution (bearer-only: true in the keycloak.json), this way the application just returns a 401 or a 403 instead of forwarding to the login page.
Using this configuration the user will never see anything from the /sso/login page and there is also no redirect issue anymore.
TLDR; the use-case I described was also not realistic, calling a REST URL and then forwarding to a login page is kind of bad stuff :)

Resources