How do I configure the spring boot quickstart for keycloak? - spring-boot

I am trying to set up a basic example spring boot site which uses keycloak for security. I have done the following
cloned and ran (gradlew bootRun) the 'complete' example from https://spring.io/guides/gs/serving-web-content/ (https://github.com/spring-guides/gs-serving-web-content.git) to verify that it works
added the following to the project's gradle dependencies:
compile("org.keycloak:keycloak-spring-boot-adapter:2.2.1.Final")
compile("org.keycloak:keycloak-tomcat8-adapter:2.2.1.Final")
put the following in config/application.yml:
spring:
profiles: default
server.port: 8090
keycloak:
securityConstraints:
- securityCollections:
- name: application section
authRoles:
- user
patterns:
- /
realm: stl
realmKey: MIIBIjANBgkqh[etc...]
auth-server-url: http://localhost:8280/auth
ssl-required: none
resource: example-ui
credentials:
secret: a117[etc...]
With these steps, I believe I've followed all the directions in https://keycloak.gitbooks.io/securing-client-applications-guide/content/v/2.2/topics/oidc/java/spring-boot-adapter.html. But now when I attempt to browse to the application, I get an error. This is what's logged to the console: No login page was defined for FORM authentication in context []
What am I missing to complete configuration of this app? From prior experience with earlier versions of other keycloak adapters, I would expect to have to specify an auth method of KEYCLOAK somewhere, but I don't know where that would go in spring boot, if indeed it goes anywhere.

Same problem here but it's only when I upgraded from Spring boot 1.4.0 to 1.4.1.
They have passed version of tomcat to 8.5.4 to 8.5.5. And every request except GET are working, only GET don't work with the message "No login page was defined for FORM authentication in context []" like you said.
Downgrading the version of tomcat did the trick for me :
<tomcat.version>8.5.4</tomcat.version>
Can someone know what's going on ?

Related

How to configure Spring OpenAPI UI behind Kong

I have a Spring Boot application and I'm using Kong as an API Gateway.
I would like to document my app's REST API with SpringDoc OpenAPI.
Everything works great locally, when I run my Spring Boot app as a standalone, but I'm facing a problem when accessing the Swagger/OpenAPI UI behind Kong.
This is my kong.yml:
services:
- name: foo
url: http://localhost:9000/foo
routes:
- name: foo-route
paths:
- /local/api/foo
methods:
- GET
- POST
- PUT
- OPTIONS
- DELETE
- PATCH
- HEAD
Assume that kong is on port 8000, and my Spring App is on port 9000.
When I hit Kong at http://localhost:8000/local/api/foo/swagger-ui.html, I get redirected to http://localhost:8000/foo/swagger-ui/index.html?configUrl=/foo/v3/api-docs/swagger-config, which is the wrong path.
How can I fix this issue?
Found a solution!
On the Spring Boot side, since I'm using a version higher than 2.2, all is needed is the following bean:
#Bean
ForwardedHeaderFilter forwardedHeaderFilter() {
return new ForwardedHeaderFilter();
}
and this configuration:
server:
forward-headers-strategy: framework
On the Kong side, since I'm using an outdated version (2.0.3), I need to add the following plugin to my kong.yml configuration file:
plugins:
- name: request-transformer
service: foo
config:
add:
headers:
- x-forwarded-prefix:/local/api/foo
from my understanding, this is not needed in newer Kong versions: as long as the host has a trusted ip, the header x-forwarded-prefix will be added automatically.

spring boot actuator endpoints unavailable after (2.5) uprade

I have attempted to take advice offered for similar problems; to no avail. Can someone please explain a resolution for this problem, as if I were six?
I've upgraded my version of spring boot to 2.5. All tests in my suite still pass, except for this #Springboot test:
#Test
void readActuatorInfo_success() throws Exception {
mockMvc.perform(
get("/actuator/info")
.header("Authorization", "Basic dXNlcjpwYXNzd29yZA=="))
.andExpect(status().isOk());
}
It fails because the response is 404. Now, I know that springboot does not, by default, expose the endpoints, that they must be explicitly configured. For example, the following yaml should do it, but no. Any tips?
application:
endpoint:
info:
enabled: true
To be clear, this test passed for Springboot 2.3
From 2.5 onwards the Info endpoint is no longer exposed by default,
The /info actuator endpoint is no longer exposed over the web by default. Additionally, if Spring Security is on the classpath and your application doesn’t have a custom security configuration, the endpoint requires authenticated access by default.
Refer to the documentation on exposing and securing actuator endpoints to change these new defaults.
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes#secure-info-endpoint
management:
endpoint:
web:
exposure: "health,info"

blocked:mixed-content error after spring boot upgrade

I have upgraded some micro services that talk to each other from Spring Boot 1.5.3 to 2.3.5.
Now when my micro service A calls micro service B, the call fails with the following status
on the network tab of chrome's developer tools (blocked:mixed-content)
I am not sure what has changed that I start getting this error.
In browser's console I get the below error:
Mixed Content: The page at 'https://gateway-url/my-endpoint' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://micro-service-b-url/login'. This request has been blocked; the content must be served over HTTPS.
The strange thing is that there is no end-point /login in my entire codebase.
I am unable to understand this behavior after springboot upgrade.
Any guidance on how spring boot upgrade led to this error and possible resolution is appreciated.
Note: I found some answers that suggest using the below code to resolve this
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
but looks like it doesn't work with all browsers and I am not sure if its safe to use this solution in terms of security.
Understood the issue and found the solution.
Looks like the security hooks used in SpringBoot 1 are deprecated in SpringBoot 2.
So in my micro-service B the below config in properties file wasn't working after upgrade
security.basic.enable: false
security.ignored=/**
as a result SpringBoot 2 was enforcing default security config on micro-service B and calls to micro-service B through gateway were being redirected to web-sso login which resulted in the mysterious /login endpoint being called.
The solution was to disable default security. I did the below steps:
1. Removed deprecated hooks from properties file:
security.basic.enable: false
security.ignored=/**
2. Disabled default security using below config
#SpringBootApplication(exclude = { SecurityAutoConfiguration.class,
ManagementWebSecurityAutoConfiguration.class })
public class MyApplication extends WebMvcConfigurerAdapter{
Note: I had to exclude ManagementWebSecurityAutoConfiguration.class because the micro-service was using SpringBoot actuator

Spring Boot 2: Refresh properties on the fly not working

I have followed this official tutorial Getting Started Centralized Configuration using spring boot 2.0.0.RELEASE and spring cloud Finchley.M8
But refreshing properties on the fly (Without restart) is not working.
After Some debugging, I noticed that in method refresh() from ContextRefresher.class, it returns the changed keys correctly, but after reconstructing the bean annotated with #RefreshScope in the next use. It still sees the old value not the updated one.
Note: This was working perfectly with spring boot v 1.5.6 and spring cloud Edgware.RELEASE.
Any help please?
Thanks
It seems spring.cloud.config.uri in spring boot 2.0.1.RELEASE always looking for port 8888 and not accepting other values, so I put the below configuration (you can ignore it, as it is the default value for the client, and the server should run on port 8888)
spring:
cloud:
config:
uri: http://localhost:8888
I also tried to expose all other services in the client for testing as follows
management:
endpoints:
web:
exposure:
include: '*'
or use the following to allow only refresh
management:
endpoints:
web:
exposure:
include: refresh
Then called POST method not GET for refreshing
$ curl -X POST localhost:8080/actuator/refresh -d {} -H "Content-Type: application/json"
Finally, it works.
Instead of Method "POST" , use "OPTIONS" method to call the "actuator/refresh" for spring boot 2.0 or higher.
For lower versions (<2.0), use the endpoint "context/refresh"
Make sure , you have management.endpoints.web.exposure.include=* defined in application.properties.
Use below in application.properties-
management.endpoint.refresh.enabled=true
management.endpoint.restart.enabled=true
management.endpoint.health.enabled=true
management.endpoint.health.show-details=always
management.endpoint.info.enabled=true
management.endpoints.web.exposure.include=info,health,refresh
Using yaml configuration file it was not working for me and when switched to properties file, it worked with above configuration.
Thanks

Spring boot application with config-server not working when using JWT authentication

I am new to using config server for getting external configuration from Github repository.
In my application.yml file of spring boot application I have used below piece of lines and it works fine when I comment JWT authentication part in my application, spring boot application can fetch updated configurations from github repository.
security:
basic:
enabled: false
management:
security:
enabled: false
My question is what if I don't include above code in my yml file, will it work fine? because when i remove above lines, it throws 401 unauthorized error.
Second thing my spring boot application is secured with JWT authentication, when I enable my JWT authentication with yml file having above piece of code, then on providing valid token also it gives 403 forbidden error.
Someone please guide me how resolve this, I am trying to resolve this from last 1 week but no luck. Thanks in advance.
I believe you have <artifactId>spring-boot-starter-security</artifactId> as a dependency in your POM.xml and therefore you will always get a 401 Unauthorized if you do not provide the default password (which you can see in logs on service startup) and if you have removed that config from your bootstrap.yml
If you are getting a 403 Forbidden, then it means that the user was able to login with credentials (means authenticated successfully) but is not "authorized" to do the action being performed. Check the roles of the user(log them or debug).

Resources