How to make Spring Boot 2 Bouncy Castle FIPS compliant? - spring-boot

I am currently trying to make a Spring Boot 2 application to follow all FIPS 140-2 requirements and use TSL in its connections by making use of Bouncy Castle Provider.
So far, I tried looking online what people been doing but it's not straightforward, for example making use of putting jars in your lib folder.
What I tried so far but I don't see how it fits together.
Application main to set Fips Provider
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleFipsProvider());
...
}
Updating java.security (which is now in jdk11/conf/security)
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
And having Bouncy castle jars in classpath of the app
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.58</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<version>1.0.2.1</version>
</dependency>
Configuring bean in Application (but then how to use it?)
#Bean
public Cipher cbcCipher() throws GeneralSecurityException {
Security.addProvider(new BouncyCastleFipsProvider());
return Cipher.getInstance("AES/CBC/PKCS7Padding", "BCFIPS");
}
Interesting pages
Usage of Native Tomcat with OpenSSL to work with Spring Boot but not Bouncy Castle https://medium.com/#crueda/tomcat-native-openssl-in-spring-boot-2-0-a341ad07471d
Bouncy Castle userguide https://downloads.bouncycastle.org/fips-java/BC-FJA-UserGuide-1.0.2.pdf
Are there any application.properties that should be set in the app?
As a note, I added the following and they work fine to read some certificate locally but not using BC FIPS
server.ssl.key-store=classpath:medium.jks
server.ssl.key-store-type=pkcs12
server.ssl.key-store-password=password
server.ssl.key-password=password
server.ssl.key-alias=medium
server.port=8080
Could you please help me see how to attach all these strings together? What am I missing? I suppose how to tell Spring Boot to use BC to its connections in the embedded web server?

Related

awspring SQS Configuration not working in Spring Boot Project

We are attempting to move away from spring cloud aws to the new io.awspring.cloud project. The documentation states:
The AmazonSQSAsync client is automatically created and passed to the template’s constructor based on the provided credentials.
I am attempting to run this locally. In my pom.xml I have added the dependency:
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-aws-messaging</artifactId>
<version>${spring.cloud.aws}</version>
</dependency>
And I removed the code to create an AmazonSQSAsync client. As per the documentation, I still define a QueueMessagingTemplate
import io.awspring.cloud.messaging.core.QueueMessagingTemplate;
import com.amazonaws.services.sqs.AmazonSQSAsync;
#Bean
#Qualifier
public QueueMessagingTemplate queueMessagingTemplateFifoSupport(AmazonSQSAsync amazonSQSAsync,
ObjectMapper objectMapper) {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setSerializedPayloadClass(String.class);
converter.setObjectMapper(objectMapper);
QueueMessagingTemplate messagingTemplate = new QueueMessagingTemplate(amazonSQSAsync);
messagingTemplate.setMessageConverter(converter);
return messagingTemplate;
}
The package namespace was updated to use io.awspring. When running the app I get the error:
No qualifying bean of type 'com.amazonaws.services.sqs.AmazonSQSAsync' available
My belief is that Spring should supply this client automatically. Am I missing something?
In my application properties I have defined:
cloud.aws.credentials.access-key
cloud.aws.credentials.secret-key
cloud.aws.region.static
I was missing a dependency:
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-aws-autoconfigure</artifactId>
<version>${spring.cloud.aws}</version>
</dependency>
which is necessary for automatic creation of default clients.
On a side note- best to avoid using this for now as you will be locked in to v1 of the Java AWS SDK until you can upgrade io.awspring to a version compatible with both a newer version of spring boot and aws

I am not able to connect to Google Cloud Memory Store from Spring Boot

I am developing a module with spring boot in my backend where i need to use Redis through GCP Memory Store. I have been searching in forum and even the "oficial documentation" about memory store but i cannot understand how to connect to memory store with my spring boot app.
I found a google code lab but they use a Compute Engine VM to install spring boot and then save and retrieve information from memory store. So i tried to do it like that in my local spring boot but it didnt work because throws an error saying:
Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 10.1.3.4
the codelab i mentioned earlier says that you only have to add this line to your application.properties:
spring.redis.host=10.1.3.4
as well as the annotation #EnableCaching in the main class and #Cachable annotation in the controller method where you try to do something with redis.
the method looks like this:
#RequestMapping("/hello/{name}")
#Cacheable("hello")
public String hello(#PathVariable String name) throws InterruptedException {
Thread.sleep(5000);
return "Hello " + name;
}
i dont know what else to do. Notice that i am new on this topic of redis and memory store.
Anyone can give me some guidance on this please?
thanks in advance
codelab url: https://codelabs.developers.google.com/codelabs/cloud-spring-cache-memorystore#0
See this documentation on how to setup Memorystore Redis instance.
Included in the documentation is how you can connect and test your Memorystore instance from different computing environments.
There's also a step by step guide on how SpringBoot can use Redis to cache with annonations.
Add the Spring Data Redis starter in your pom.xml if you're using Maven for your project setup.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Add this configuration in your application.properties file:
spring.redis.host=<MEMORYSTORE_REDIS_IP>
# Configure default TTL, e.g., 10 minutes
spring.cache.redis.time-to-live=600000
Turn on caching capability explicitly with the #EnableCaching annotation:
#SpringBootApplication
#EnableCaching
class DemoApplication {
...
}
Once you configured the Spring Boot with Redis and enabled caching, you can use the #Cacheable annotation to cache return values.
#Service
class OrderService {
private final OrderRepository orderRepository;
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
#Cacheable("order")
public Order getOrder(Long id) {
orderRepository.findById(id);
}
}

Spring Boot 2.4.3 - Actuator /startup endpoint not found

I have a spring boot app that I upgraded from v2.2.x to now be v2.4.3.
I saw in their documentation that there is a new actuator endpoint of /startup, however it does not exist when I start my app.
There is no special requirement according to their documentation here
I am using spring-boot-admin-starter-client v2.4.3 which provides spring-boot-actuator v2.4.3, and i even have management.endpoint.startup.enabled=true in my application.properties file.
Has anyone else used this version of spring boot and gotten this actuator enpoint to work?
You need to tweak startup configuration:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setApplicationStartup(new BufferingApplicationStartup(1000));
app.run(args);
}
}
In application.properties:
management.endpoints.web.exposure.include=startup
If you want to visualize startup events check out this tool I made some months ago https://spring-boot-startup-analyzer.netlify.app/ (look at the configuration instructions as you need to enable CORS on this endpoint)
May be you are using BootstrapApplicationListener which build the application context again but ignores the previous applicationStartup, so it sets the default, this is a bug in spring-cloud-context:3.0.0

How to use OpenApi annotations in spring-webflux RouterFunction endpoints?

I am currently working on a project where I use spring functional web programming. I usually use annotations of swagger 2 in restController but with functional web programming I can not find where ! The place to tell the app to do a search for endpoints (like basepackage in Docket) and load swagger in an html page.
Here is my code:
#Configuration
public class RouterClient{
#Bean
public RouterFunction<ServerResponse> routes(ClientHandler client){
return route(GET("/api/client"), client::findAll)
.andRoute(POST("/api/client"),client::add);
}
}
Config Class:
#Configuration
public class OpenApiConfiguration{
#Bean
public GroupedOpenApi groupOpenApi() {
String paths[] = {"/api/**"};
String packagesToscan[] = {"com.demo.client"};
return GroupedOpenApi.builder().setGroup("groups").pathsToMatch(paths).packagesToScan(packagesToscan)
.build();
}
}
The dependencies:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-core</artifactId>
<version>1.2.32</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>1.2.32</version>
</dependency>
The result :
Functional endpoints are supported since 1.3.8 (early May). See releases on GitHub.
Have a look at this: https://springdoc.org/#spring-webfluxwebmvc-fn-with-functional-endpoints
The easiest way to see your endpoints on the Swagger UI is to add the #RouterOperation annotation to your RouterFunction methods (containing a single route), and specify the beanClass and beanMethod used in it. However, in your case, there are multiple routes on a single method, so you must also use the #RouterOperations annotation. These cases are well documented in the link above.
It seems like the current implementation of springdoc-openapi only allows to manually add the documentation.
set
springdoc.api-docs.enabled=false
This will skip classpath scanning (springfox) for the API annotations. (OAS3 replaced these in v3) and replace them with reading in the spec file (json/yaml).
Put the documentation in the Spec files, as one can generate any number of clients from these. Easiest way to start with legacy code is to copy the /api-docs/ files generated by springfox.
You can go to editor.swagger.io, load in the version 2 yaml and convert it to version 3 if springfox still doesn't do that. Then work with yaml files. (it's a contract UP-Front specification for a reason)
https://springdoc.org/
You need springdoc-openapi-webflux-ui and #RouterOperation.
spring-webflux with Functional Endpoints, will be available in the future release

Configuring the AJP port on Jetty in a Spring boot application

I am trying to configure the AJP port for the Jetty server in my spring boot application. However, I've seen examples about the Tomcat AJP connector but not for Jetty. Can someone tell me how I should configure the AJP port on Jetty?
Spring boot bundles Jetty 9.3 by default. The AJP feature has been droped in jetty 9. If you really need to use AJP, then you will have to add jetty 8 to your classpath, and write a custom JettyServerCustomizer (http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/context/embedded/jetty/JettyServerCustomizer.html).
I don't think you will find anything in spring documentation regarding this configuration. Once you get to write your customizer, you'll have to read through Jetty documentation to find out how to achieve your AJP configuration.
Jetty has droped AJP in favor of HTTP connector. Unless you have a real use case, I would avise to migrate to HTTP.
I haven't tried the code, but this should work (needs to be wrapped in spring boot code)
return new JettyServerCustomizer() {
#Override
public void customize(Server server) {
s.addConnector(new Ajp13SocketConnector());
}
};
You need jetty-server 8.x and jetty-ajp 8.x in your classpath. With latest 8.x releases, your pom.xml (if you're a maven user) should contain:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>8.1.19.v20160209</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-ajp</artifactId>
<version>8.1.19.v20160209</version>
</dependency>
Full Sample of The Example Suggested Above For anyone's reference
#Bean
public EmbeddedServletContainerFactory jettyContainer() {
JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
JettyServerCustomizer customizers = new JettyServerCustomizer() {
#Override
public void customize(Server server) {
// Connector connector = new Ajp13SocketConnector();
// connector.setPort(9009); //if you want a custom port
server.addConnector(new Ajp13SocketConnector());
}
};
factory.addServerCustomizers(customizers);
return factory;
}
Logs
o.e.jetty.server.AbstractConnector: Started
SelectChannelConnector#0.0.0.0:7090 o.e.jetty.server.AbstractConnector
: Started Ajp13SocketConnector#0.0.0.0:9009
o.e.jetty.ajp.Ajp13SocketConnector : AJP13 is not a secure protocol.
Please protect port 9009 .s.b.c.e.j.JettyEmbeddedServletContainer :
Jetty started on port(s) 7090, 9009

Resources