Spring Kafka Ssl Implemantation without using trust/keystores - spring

Hi I want to implement ssl feature in my spring kafka connection.To achive this I have to set SslTruststoreLocation,SslKeystoreLocations.But is it possible not to set classpath.Can I give the content o cert file as a string and running ssl implemantation like that?Is there any change to do that
Normal way we can set this properties
spring:
kafka:
ssl:
key-password: pass
keystore-location: /tmp/kafka.client.keystore.jks
keystore-password: pass
truststore-location: /tmp/kafka.client.truststore.jks
truststore-password: pass
What I want to to set cert file content and running spring kafka implemantation

Related

Setting end session endpoint

With a Spring Boot client configured in the DMZ and Spring Security OAuth configured using:
issuer-uri: https://authentication_server/auth/realms/my-realm
I get this error from Spring Security:
The Issuer "https://external_url/auth/realms/my-realm" provided in the configuration metadata did not match the requested issuer "https://authentication_server/auth/realms/my-realm
From this post I have learned that I need to specify authorization-uri, token-uri and jwk-set-uri instead of issuer-uri, and then it also works.
authorization-uri: https://external_url/auth/realms/my-realm/protocol/openid-connect/auth
token-uri: https://authentication_server/auth/realms/my-realm/protocol/openid-connect/token
jwk-set-uri: https://authentication_server/auth/realms/my-realm/protocol/openid-connect/certs
(I do not get why Spring Security cannot auto-configure with the same values from the issuer-uri when it works setting the values individually)
Now the problem is that logout stops working. When using issuer-uri the OAuth is auto-configured and end_session_endpoint is fetched from the answer, but when specifying each setting there is no way to specify the end_session_endpoint.
Is this an outstanding issue in Spring Security OAuth, or do I need to configure it differently?
I had to make a work around for this. With little time I started by copying the existing OidcClientInitiatedLogoutSuccessHandler which I already were using in configuring LogoutRedirectUri.
I simply copied the class and changed the implementation of the method endSessionEndpoint() to return the URI which is returned by our OAuth server as end_session_endpoint.
This issue is tracked in spring-security GitHub.
Probable fix will be allowing to add "Additional attributes for ClientRegistration and ProviderDetails".

Spring boot 2.4.x cannot handle multi document yml files from config server

Java version: 8
Spring Boot version: 2.4.1
Spring Cloud version: 2020.0.0, specifically I use a Spring Cloud Config Server connected to GIT and our services are Spring Cloud Config Clients.
I have migrated away from using bootstrap.yml and started using spring.config.import and spring.config.activate.on-profile as mentioned in the documentation here and here
My configuration in my service, who is a client to the config server looks like this:
server.port: 9001
spring:
application.name: my-rest-service
config.import: configserver:http://localhost:8888
cloud.config.profile: ${spring.profiles.active}
My configuration in the config server looks like this:
application.yml (has two documents separated by the ---)
logging:
file.name: <omitted>
level:
root: INFO
---
spring:
config.activate.on-profile: dev
logging.level.root: DEBUG
my-rest-sercive.yml (has two documents separated by the ---)
spring:
datasource:
driver-class-name: <omitted>
username: <omitted>
password: <omitted>
---
spring:
config.activate.on-profile: dev
datasource.url: <omitted>
Because there is a profile "dev" active, I successfully get the following 4 configurations from config server:
application.yml: general logging level
application.yml: specific logging for dev
my-rest-sercive.yml: general datasource properties
my-rest-sercive.yml: specific datasource url for dev
I can see these 4 sources successfully being fetched when I use my browser or when I debug or in the logs when I lower the loglevel to trace:
o.s.b.c.config.ConfigDataEnvironment : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\my-rest-service.yml'
o.s.b.c.config.ConfigDataEnvironment : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\my-rest-service.yml'
o.s.b.c.config.ConfigDataEnvironment : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\application.yml'
o.s.b.c.config.ConfigDataEnvironment : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\application.yml'
However, notice that because I use multi document yml files, out of these 4 property sources only TWO unique names are used.
In a later step, when Spring creates the data source bean, he complains he cannot find the data source URL. If I debug the spring bean factory I can indeed see that out of the 4 property files returned by the config server, only two have remained (the ones that don't contain the dev profile specific configuration). I assume this is because they have an identical name and they overwrite each other. This is an effect of this piece of code in the MutablePropertySource.class:
public void addLast(PropertySource<?> propertySource) {
synchronized(this.propertySourceList) {
this.removeIfPresent(propertySource); <-- this is the culrprit!
this.propertySourceList.add(propertySource);
}
}
This is a breaking change from Spring 2.3/Spring Cloud Hoxton where it correctly collected all properties. I think spring cloud needs to change the config server so that every document within a yml has has a unique name when returned to Spring. This is exactly how Spring Boot handles multi document yml files, by appending the String (documenyt #1) to the property source name
I found an interesting note about profiles and multi document yml, basically saying it is not supported, but this doesn't apply to my use case because my yml files are not profiles based (there is no -{profileName} in the last part of the file name).
This is a known issue with the new release. We can track the issue here on the spring cloud config server github page.
The workaround seems to be stop using multi document yml files and use multiple distinct files with the profile name in the filename.

Configuring consumerWindowSize in Spring Boot application

ActiveMQ Artemis configuration file in Spring Boot below:
spring:
artemis:
host: localhost
port: 61616
user: admin
password: admin123
There is no properties for broker-url so that I can set consumerWindowSize like
tcp://localhost:61616?consumerWindowSize=0`
How can i configured consumerWindowSize in a Spring Boot application.
Based on the Spring Boot documentation (which references ArtemisProperties) I don't believe you can set the broker's actual URL or any of the properties associated with it. This is a pretty serious short-coming of the Artemis Spring Boot integration as it really limits the configuration. There is already an issue open to (hopefully) address this.
Added below configuration to solve this issue:
#Bean("connectionFactory")
public ConnectionFactory connectionFactory(AppProperties appProperties) {
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory($brokerUrl);
cf.setUser($user);
cf.setPassword($password);
return cf;
}

Feign Client Prioritizing URL's in yaml over Eureka

I have a Spring Boot application which serves as a Eureka client. The application has the need to call another micro-service through REST, and I wish to make this call using Feign. The issue I am having is, my application is trying to lookup the service name in Eureka, when it is only defined in my applications yaml file.
I apologize for the hard to follow explanation, hopefully the following code snippets will help clarify.
Feign client:
#FeignClient("foo")
#Component
public interface FooServiceProxy{
#RequestMapping(value = "/balance", method = RequestMethod.POST, produces = "application/json")
ServiceResponse execute(ServiceRequest serviceRequest);
}
In my controller who calls this Feign client, the FooServiceProxy is defined using #AutoWired:
#Autowired
private FooServiceProxy fooServiceProxy;
My yaml file is as follows:
spring:
application:
name: app-name
server:
port: 8080
foo:
ribbon:
listOfServers: http://hostname:8081/balance
eureka:
client:
fetchRegistry: false
serviceUrl:
defaultZone: http://eurekasrver:8761/eureka/
My issue is, during run-time, the following error is thrown:
java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: foo
Interestingly, if I remove the #EnableEurekaClient annotation from the application, everything works. I believe I understand the problem which is that instead of looking up the server for foo in my yaml file, because the application is a Eureka client, Feign is going straight to Eureka to lookup a server ip, then failing as none can be found. Despite seeming to understand the problem, I have been unable to find a solution online or to think of one myself.
Any help will be appreciated.
Thank you!
Concerning this question, you should take in account that when eureka is on your classpath, all ribbon configuration are charged by eureka, so it'll use eureka server's list.
Spring Cloud uses #RibbonClient to configure the types used by ribbon, like server list. If you have eureka on the classpath, by default it uses the eureka server list (hence your need for the flag to disable eureka).
Commented by spencergibb https://github.com/spring-cloud/spring-cloud-netflix/issues/564
You can try either by adding the NIWSServerListClassName configuration:
`someservice.ribbon:
NIWSServerListClassName:com.netflix.loadbalancer.ConfigurationBasedServerList
listOfServers: server1:80`
Or try the solution proposed in this issue https://github.com/spring-cloud/spring-cloud-netflix/issues/564

Spring boot JDBC with password lease/renew (as in Vault)

Hashicorp's Vault can be set up to provide database passwords on demand; each password can be used for a certain "lease" period (say 1 hour) before being renewed, and a maximum use period can be set after which the password has to be trashed and a new one obtained.
In Spring Boot, the JDBC connection is configured at application start, and it is assumed that the JDBC password is coded in the application.properties file (or, alternatively, obtained at application bootstrap time via Spring Cloud Config or equivalent) and used forever.
QUESTION: How might I implement a way in Spring Boot to reset the JDBC password by accessing Vault when a connection attempt fails due to an expired password?
Is there a way to set some sort of handler gets invoked when the connection fails due to an old password, and resets it to a new value?
Check out this open source project available on GitHub; I think it might just be what you are looking for. Note: From the looks of it, this is currently a Spring Cloud Incubator project (has the potential of becoming an official Spring endorsed open source library in the future), and there are only three contributors. You would have to see if it is "reliable enough" to suit your needs.
https://github.com/spring-cloud-incubator/spring-cloud-vault-config
--- Here's a quick summary of useful information ---
Add the following dependency to pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-starter-config</artifactId>
<version>x.y.z</version>
</dependency>
Create a standard Spring Boot application - provided example is just a main application class:
#SpringBootApplication
#RestController
public class Application {
#RequestMapping("/")
public String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
When it runs it will pick up the external configuration from the
default local Vault server on port 8200 if it is running. To modify
the startup behavior you can change the location of the Vault server
using bootstrap.properties (like application.properties but for the
bootstrap phase of an application context), e.g.
bootstrap.yml:
spring.cloud.vault:
host: localhost
port: 8200
scheme: http
connection-timeout: 5000
read-timeout: 15000
host sets the hostname of the Vault host. The host name will be used for SSL certificate validation
port sets the Vault port
scheme setting the scheme to http will use plain HTTP. Supported schemes are http and https.
connection-timeout sets the connection timeout in milliseconds
read-timeout sets the read timeout in milliseconds

Resources