Keycloak Docker setup with Spring - java

I want to deploy a Spring microservices application using Docker Compose.
I have a Keycloak container running with a public Authorization Code Flow (with PKCE) client configured and now I want to authenticate with a webapp that's hosted on another server or with a mobile app.
I have set the KC_HOSTNAME_URL of the Keycloak container to the public IP like http://1.2.3.4:8080 and in my webapp I have set the authority URL to http://1.2.3.4:8080/realms/my-realm (using oidc-react package).
This way general authentication with Keycloak works.
But when I want to make a request to one of my services with the received token, Spring gives me the error:
java.lang.IllegalStateException: The Issuer "http://1.2.3.4:8080/realms/my-realm" provided in the configuration did not match the requested issuer "http://keycloak:8080/realms/my-realm"
This makes sense, because my services are configured with spring.security.oauth2.resourceserver.jwt.issuer-uri=http://keycloak:8080/realms/my-realm, when running inside docker.
I just don't know what I am missing in order to obtain a token using a public IP/Domain from a public client on the one hand and on the other hand validating that token inside docker using docker-internal names.

Related

SpringBoot, Keycloak adapter, Kubernetes: Failed to load URLs from pod.namespace

I am using the keycloak adapter for springboot to manage the authentication.
In localhost it works well with an URL for Keycloak like "https://kc.dev.com/auth"
But when I deploy the app in Kubernetes cluster, the Keycloak adapter cannot reach the keycloak server because of the URL I configured "service.namespace:port/auth"
It doesn't work here, even with the http client feign it is working for another need.
If someone knows how to fix it...
Please let me know

spring boot actuator refreshscope

I have an application which is running on multiple AWS hosts behind a load balancer. All of these instances load the configuration from a spring config server. I can use spring boot admin server to identify the the URL's so that I can execute the POST at hostname:port/actuator/refresh command for individual host using POSTMAN. As the number of hosts increase, it becomes difficult to run a command for each one of the hosts. Is there a way I can do the same with a single command?
We use something similar for our application
i.e Spring applications fetching properties from config server and a spring boot admin server to which all these application registers.
We have exposed an post api in bootadmin which calls refresh endpoint on all instances of specified app.
Since bootadmin has all information about registered apps, we are using it to 'publish' message to all 'subscribed' apps.

How do http requests work in deployed Spring Boot app?

Can someone explain how hosting works ? in my spring boot app there'ss embedded tomcat server. as I understand the spring app runs with tomcat, tomcat takes some port, 8080 for example, and listens to requests coming to that port (when deployed locally at least) localhost:8080. I can make requests from my front end app, which runs on localhost:3000 and tomcat will take the requests, find controllers mapped to the urls that front request is directed to "/user" or "/myposts" or whatever, that controller runs code, talks to db inserts data into response and tomcat sends it back to front end.
If I deploy my app to some hosting service, like Google cloud, does the spring app still run with tomcat ? in that case which port will tomcat run on, where would my front end send requests to ? to the subdomain that google cloud has set up for my project ? Where would i need to configure SSL/https ? Would my front end send secure requests to google subdomain over https endpoints and it would relay those requests to deployed spring app through http(unsecured, inside hosting server) ? Or how ?
One of the most straightforward way to do this is to spin up an instance, ssh into the that instance and run your spring boot app the same way you would run it on your machine. Everything works the same as it would on that cloud instance. Your spring boot app still runs within tomcat and it still listens to port 8080. The only difference is now the hostname is no longer localhost and it will be the DNS name of that instance. You can find the DNS name on the console.
You need to get a SSL certificate if you wanna enable https "natively" in your spring boot app. Alternatively, you can set up a load balancer or an API gateway in front of your cloud instance to do the SSL termination for you. In this case, your frontend will send request to the load balancer or API gateway instead of your spring boot app. They accept https requests and transform them to http request and send it to your spring boot app.

OAuth2 Client And Resource Server in same application

I'm creating an Authentication Server and which some of my existing applications can use to authenticate. I'm using the OAuth2 with Spring Boot by following this sample project and tutorial https://github.com/dynamind/spring-boot-security-oauth2-minimal.
But in my case my existing applications are built using Spring MVC and angular. So there is no separate Resource Server. Resources are also located in same application(Resources are my Secured Request Mappings in same application).I just want to separate the authentication process from my client applications and use a common Authorization Server. (Currently they use the Google Authentication + Spring Security to secure the application).
So I tried to use #EnableResourceServer and #EnableOAuth2Client in same application but I could not get the expected results.
What is the best way to achieve this task?? Is there any other method that I can follow to authenticate my applications from Oauth2 Server?
You need to configure your web security for form based login and Resource Server Security form REST Endpoints
See my answer to the similar question here

Spring Security - Custom LDAP Authentication

I came across a difficult scenario with my Spring MVC web application.
My application is using LDAP authentication. When I hosted this application in outside could environment, the authentication failed as there is no public LDAP url for my organization. They don't have public LDAP url due to security reasons.
Is it possible, that I create a authentication service inside my organization network and and my application hit that service every time a user tries to authenticate??
How can I separate authentication from my application?
For this You have to deploy 2 applications. First one is a service application in your organization network. This service will be called from your outside application for authentication purposes.

Categories