How to use the default keycloak.json instead of spring properties - spring-boot

I was following this example to set up keycloak with springboot
https://www.baeldung.com/spring-boot-keycloak
I have used the bellow bean so I can use spring boot properties file.
which all worked fine.
But if I wanted to use the Keycloak.json file instead of spring boot properties, what I did was commented out the KeycloakSpringBootConfigResolver been and included the keycloak.json file in resources/WEB-INF/keycloak.json. but I keep getting the following error.
am I missing something? how do I use the keycloak.json file and where should this file go? or is there some configuration I missed? all the examples show using spring properties and not json file. Any ideas? or if you could point me to an example that uses the default keycloak.json
Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.keycloak.adapters.springboot.KeycloakAutoConfiguration': Unsatisfied dependency expressed through method 'setKeycloakSpringBootProperties' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
#Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}

Add this to your configuration file:
keycloak:
configurationFile: "classpath:keycloak.json"
Put the keycloak.json directly into the resources directory.
Use only keycloak adapter as dependency: org.keycloak:keycloak-spring-security-adapter

Related

Spring Cloud Config Server with GIT Repo configured is not starting up successfully

I am building Spring Cloud Config server with Sprint Boot v2.6.12 and Spring Cloud Config Server v3.1.1. Below is the application.yml configuration,
spring:
application:
name: config-server
main:
allow-bean-definition-overriding: true
cloud:
config:
server:
git:
uri: git#github.aus.thenational.com:demo/case_configuration.git
skip-ssl-validation: true
default-label: master
clone-on-start: true
clone-submodules: true
force-pull: true
refresh-rate: 60
search-paths:
- case/folder1
- case/folder2
Exception we are getting while server startup is as below,
2022-12-21 09:51:10.827 WARN 11524 --- [main] [CID:] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthContributorRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Unsatisfied dependency expressed through method 'healthContributorRegistry' parameter 2; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'configServerHealthIndicator' defined in class path resource [org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration$ConfigServerActuatorConfiguration.class]: Unsatisfied dependency expressed through method 'configServerHealthIndicator' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'searchPathCompositeEnvironmentRepository' defined in class path resource [org/springframework/cloud/config/server/config/CompositeConfiguration.class]: Unsatisfied dependency expressed through method 'searchPathCompositeEnvironmentRepository' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'defaultEnvironmentRepository' defined in class path resource [org/springframework/cloud/config/server/config/DefaultRepositoryConfiguration.class]: Unsatisfied dependency expressed through method 'defaultEnvironmentRepository' parameter 1; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'multipleJGitEnvironmentProperties' is expected to be of type 'org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties' but was actually of type 'com.sun.proxy.$Proxy140'
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'multipleJGitEnvironmentProperties' could not be injected because it is a JDK dynamic proxy
The bean is of type 'com.sun.proxy.$Proxy140' and implements:
org.springframework.cloud.config.server.support.HttpEnvironmentRepositoryProperties
org.springframework.cloud.config.server.support.EnvironmentRepositoryProperties
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
org.springframework.core.DecoratingProxy
Expected a bean of type 'org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties' which implements:
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on #EnableAsync and/or #EnableCaching.
I tried configuring http and https proxy settings along with other GIT configurations. But that didnt work.
Expectation is, config server should be up successfully.
Tried to solve the issue by configuring spring AOP related configurations in application.yml , but that didnt work too.
Seems like something something to do with libraries versions.

Disabling Spring Security leads to Failed to load application context

I am disabling Spring Security for the test profile as below:
spring:
config:
activate:
on-profile: test
autoconfigure:
exclude[0]: org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration
exclude[1]: org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration
Error:
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientConfigurations$ReactiveOAuth2ClientConfiguration$SecurityWebFilterChainConfiguration.class]: Unsatisfied dependency expressed through method 'springSecurityFilterChain' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.web.server.ServerHttpSecurity' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
A small clarification that you are not disabling Spring Security, you are disabling the Spring Boot auto-configuration of Spring Security. You can read more about that in the Spring Boot reference documentation.
In your configuration you are disabling the ReactiveSecurityAutoConfiguration, but the ReactiveOAuth2ClientAutoConfiguration is still enabled, presumably because you have a dependency such as spring-boot-starter-oauth2-client.
As described in the error message, the ReactiveOAuth2ClientAutoConfiguration is attempting to create a SecurityWebFilterChain bean, but cannot inject the required ServerHttpSecurity bean, because the ReactiveSecurityAutoConfiguration is disabled.
To fix the error message, you can disable the OAuth 2.0 client auto-configuration as well.
spring:
autoconfigure:
exclude[0]: org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration
exclude[1]: org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration
exclude[2]: org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration
I am using the okta-spring-boot-starter and this worked for me:
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration
- org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration
- org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration

spring boot to Tomcat deployment data source issue

I am building an application with Spring Boot, Neo4j and MongoDB. I have used #Configuration annotation to load database properties from application.properties like this:
#Bean(name = "neoDriver")
#Profile("local")
public Driver getNeoDriver() {
return GraphDatabase.driver(
env.getProperty("datasource.neo4j.uri"),
AuthTokens.basic(env.getProperty("datasource.neo4j.username"), env.getProperty("datasource.neo4j.password")),
Config.build().toConfig());
}
The autowire code is
#Autowired
#Qualifier("neoDriver")
private Driver neoDriver;
when I run the application from IntelliJ, it runs fine; but when I try deploy the war file on Tomcat 8.5, it gives error.
Field neoDriver in com......repository.PositionRepositoryImpl required a bean of type 'org.neo4j.driver.v1.Driver' that could not be found.
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'Controller': Unsatisfied dependency expressed through field 'positionService'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'Service': Unsatisfied dependency expressed through field 'positionRepository'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'RepositoryImpl': Unsatisfied dependency expressed through field 'neoDriver'; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.neo4j.driver.v1.Driver' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true), #org.springframework.beans.factory.annotation.Qualifier(value=neoDriver)}
Please let me know what did I do wrong when deploying this on Tomcat.
I bet you're not setting spring.profiles.active to local in your Tomcat deployment. Because your bean is marked with the #Profile annotation, so it will only be created if that profile is active.

configure dataSource for liquibase in spring boot

I have a spring boot application and I want to add liquibase configuration change log for it.
I have created a LiquibaseConfig class for configuring liquibase:
#Configuration
public class LiquibaseConfiguration {
#Value("${com.foo.bar.liquibase.changelog}")
private String changelog;
#Autowired
MysqlDataSource dataSource;
#Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog(changelog);
return liquibase;
}
}
and I have configured the datasource information in properties file:
spring.datasource.url=jdbc:mysql://localhost:3306/dms
spring.datasource.username=root
spring.datasource.password=test
spring.datasource.testWhileIdle = true
spring.jpa.show-sql = true
#liquibase
com.foo.bar.liquibase.changelog=classpath:/db/changelog/db.changelog.xml
when I run my application I receive this error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'liquibaseConfiguration': Unsatisfied dependency expressed through field 'dataSource': No qualifying bean of type [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] found for dependency [com.mysql.jdbc.jdbc2.optional.MysqlDataSource]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] found for dependency [com.mysql.jdbc.jdbc2.optional.MysqlDataSource]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Now I understood that this means the application cannot autowire the MysqlDataSource dataSource; but I need to pass the data source to liquibase bean. How can I do that?
Here's a simple step to integrate liquibase in spring boot
STEP 1
Add liquibase dependency
Gradle
runtime "org.liquibase:liquibase-core"
Maven
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<scope>runtime</scope>
</dependency>
STEP 2
Add liquibase changelog file path in application.yml
liquibase:
enabled: true #this is optional as enabled by default
change-log: classpath:/liquibase/db-changelog.xml
Notice property liquibase.change-log. I'm referring path as /liquibase/db-changelog.xml. so you should have a file name db-changelog.xml inside src/main/resources/liquibase/
STEP 3
Add your changesets on the file and when Spring-Boot application is started (spring-boot:run) your changeset will be loaded.
This will use default dataSource that your app uses.
More Info: http://docs.spring.io/spring-boot/docs/1.4.3.RELEASE/reference/htmlsingle/#howto-execute-liquibase-database-migrations-on-startup
Update
For Spring Boot 2.0 as #veben pointed out in comment use
spring:
liquibase:
change-log: #path
Rather than autowire the datasource, create a method in your Liquibase Configuration Object to create the datasource.
private DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUsername("user");
dataSource.setPassword("pswd");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/db");
dataSource.setSchema("dbName");
return dataSource;
}
then in your bean generation method
liquibase.setDataSource(dataSource());
This gives you a chance to specify the database parameters on the fly, I still had the changelog location in the applications.properties file along with the enablement of liquibase. I've tried it, and it works for me.
I had a similar construct for my application, have you tried injecting a more generic javax.sql.DataSource instead?
My guess is that Spring uses the non-specific type for this bean, on top of that you shouldn't even use a database-specific type if your application could be configured to use a totally different source, i.e. by just changing the datasource URL in the configuration file.

Boot, OAuth2, Zuul Proxy and Versions

So, i've added in Zuul and to get the proxy working realised i needs to add in 'spring-cloud-security' which i did:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-security</artifactId>
<version>1.1.0.M2</version>
</dependency>
The trouble is that as soon as i do this i get this exception
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loadBalancedOauth2RestTemplate' defined in class path resource [org/springframework/cloud/security/oauth2/client/ OAuth2LoadBalancerClientAutoConfiguration$LoadBalancedOauth2RestTemplateConfig.class]: Unsatisfied dependency expressed through constructor argument with index 2 of typ[org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails]: : No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
if i do make a bean i get this exception (i'm specifying the resource server info outside of props/yml):
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.security.oauth2.client.OAuth2RestTemplate] is defined: expected single matching bean but found 2: userInfoRestTemplate,loadBalancedOauth2RestTemplate
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
I've been through this previous post:
https://github.com/spring-cloud/spring-cloud-security/issues/73
I'm using Spring Boot 1.3.3.RELEASE. I've tried (form the above posting) adding in to dep management:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
but to no avail.
I expect this is a 'versions' issue; what is the most recent set of libs & versions to use? I've been through the 'oauth2-vanilla-ui' sample in the AngularJS/Security tutorial. Is it because i'm not using props in the resource file?
Ok, so i managed to figure it out. So i upped the version of 'spring-cloud-security' to '1.1.0.M4' as I noticed some of the autoconf had changed. Also, i left my 'OAuth2ProtectedResourceDetails' as a bean and added an 'OAuth2RestTemplate' bean but, crucially, marked it as primary:
#Primary
#Bean(name = "platformClientRestTemplate")
public OAuth2RestTemplate clientRestTemplate() {
return new OAuth2RestTemplate(platformOAuth2ProtectedResourceDetails(), oauth2ClientContext);
}
this means the problem of multiple RestTemplates goes away (and ensures the rest template i want gets used).
This means i'm using (for anyone with version issues):
Boot 1.3.3.RELEASE
spring-cloud-security 1.1.0.M4
spring-cloud-starter-zuul 1.1.0.M3

Resources