Could you please let me know by default whether the spring RestTemplate do certificate revocation status check? If yes, which one it does CRL or OCSP? or If I do the JVM settings it will take as per the JVM settings.
I am not able to find it from any documentation.
I use spring-boot 1.3.5
This is not easy to answer cause RestTemplate is using a ClientHttpRequestFactory to create Requests which will then be executed. The default one which is being used is SimpleClientHttpRequestFactory that uses JDK internals and should let you manipulate its behavior by passing in JVM settings. I'm not aware of the details of the JVM but I think you can configure if it should check CRL, OCSP or both as well as some other things.
But if you are using a different one like Netty4ClientHttppRequestFactory, HttpComponentsClientHttpRequestFactory or OkHttp3ClientHttpRequestFactory the behavior might be different cause the implementation behind might be a different one. In these cases I suggest you have a look at the documentation of those projects.
Hope that helps.
Related
I have a Java (11) Spring Boot microservice using the Spring Kafka starter (together with an Axual wrapper, but this is probably not relevant). My business requires authenticating to the cluster using SSL. I have set up things locally and it's all working neatly.
But now I am tasked with organising the project and the configuration in a secure and proper way, which primarily includes separating the SSL keystore, truststore and the passwords from the source code repo. In my local setup I have them in my resources directory as .jks files.
The current setup for storing secrets is using a Spring Config Server that we connect to using Spring cloud. This SCS has a Credhub instance that can be used to store secrets. in another project that uses SSL for an mTLS connection with a third party API, I have stored the certificates in base64 in this credhub, and then load them into a bean when the app boots up. Here I use the Java.net.ssl SSLContext class and the java.security Keystore class to build a keystore and a truststore in code, then inject the SSLContext bean into a RestTemplate bean and without going into the specifics, voila it is configured.
I was hoping to do something similar in Spring kafka. But whereas the Spring RestTemplate can be constructed using a bunch of factory classes that at their base take in this SSLContext object, I struggle to find the way the ConsumerFactory can be configured except by supplying a property in the KafkaProperties that points to an already made .JKS file.
I was looking to build up my SSLContext or simply my KeyStore object in Java, inject it as a Spring bean and use it to configure the factory. Now, the KeyStore class has a 'store(.., ..)' method that can be used to create a .jks file - but this seems a roundabout way of doing it. It just seems a bit hacky to do it that way.
The way I see it, I have a few options.
A: find a way to inject the SSL config as a bean and configure the factory in code
B: load the SSL config in java in code, then save it as a file for the Spring Kafka to load normally
C: Inject the .jks file in the pipeline from a secure location into the container
D: inject the .jks file into the container on boot-up through another kind of secret storage solution
I prefer option A because I like working the framework and deepening my understanding.
Option B seems, like I said, hacky. But perhaps someone here will tell me it's totally fine. Then I would like to know how best to do this. Do I simply call the .store() in my ConsumerFactory bean before I return it? Can I extend or configure the SpringApplication.run() to maybe execute this creating and storing of the keystore file before loading all the other beans? Any ideas would be welcome.
Option C and D will solve my issue. They may even be the better solutions. But for my own understanding of the framework, if you can help me figure out A (or possibly B) I would love to hear it. If then the conclusion is still "go for C you're better off that way" then at least I know the ins and outs of it.
It's not entirely clear what you mean, but the factory (producer and consumer) has updateConfigs().
/**
* Update the consumer configuration map; useful for situations such as
* credential rotation.
* #param updates the configuration properties to update.
* #since 2.7
*/
default void updateConfigs(Map<String, Object> updates) {
}
For option A, you can inject Boot's auto configured factories into another #Bean definition and mutate the configs there.
I don't think the kafka-clients code provides a mechanism to inject your own SSLContext, but I could be wrong.
The code-base I work with has a working OAuth model that uses OAuth2RestTemplate to manage access-tokens & access-token requests. As OAuth2RestTemplate is deprecated, I want to move to Spring Security OAuth & WebClient.
When I looked at some of the classes involved, I was surprised to see that OAuth2AccessTokenResponseClient does not return a Mono, and the default implementation - DefaultPasswordTokenResponseClient - uses RestTemplate internally.
I thought one of the primary advantages of WebClient was that it was non-blocking? If that is the case, why is blocking I/O one of the default strategies for requesting access-tokens? From the perspective of someone new to reactive/WebClient, I do not understand why the OAuth2AccessTokenResponseClient isn't itself a WebClient instance.
If I try to write a custom filter that uses WebClient to request the token, will I encounter major roadblocks or hard-to-detect bugs? I do not have much knowledge to build off in this area but would still appreciate if someone could try to help out.
You are wrong a little: OAuth2RestTemplate is not deprecated; since Spring version 2.2.0 plenty classes are moved to new and other libraries, Spring left in OAuth module only the Authentication server, all other classes annotated as deprecated. OAuth2RestTemplate is used further, just with another package.
In light of this you can use RestTemplate further, but with changes in a project. Or, of course, to move to WebClient. This approach is not better or worse, it's just can work asynchronous and non-blocking.
We in our projects decided while not to move to new version, waiting for clear and fully understandable documentation about migration (at least last month it was not full and not fully understandable).
I am having an architectural issue with the Apache HttpComponents HttpClient.
We have a system where we have several different remote endpoints that we want to contact, and each have some different configurations like ssl, basic auth, et cetera.
I am using Spring Boot and Cloud Sleuth from which I get a HttpClientBuilder that gives me tracing and other things. I want to re-use that HttpClientBuilder but on-top of that add my own specific configurations, for each unique endpoint.
The problem though is that the HttpCientBuilder is not immutable with withXYZ() methods, nor is there a copy or clone method on the builder, so I can't copy the original and change just my specific changes there without altering the base HttpClientBuilder and get into conflicts with others that use the same instance of the builder. Be it racing conditions between threads or conflicting configurations between the different endpoints.
One place in the Spring Boot project where I have seen them seemingly wanting to do something similar is in HttpClientConfiguration of Spring Cloud Commons where it creates an own ApacheHttpClientFactory which takes the original autowired HttpClientBuilder and then sets disableContentCompression(), disableCookieManagement() and useSystemProperties() -- but it seemingly does it to the original instance of the HttpClientBuilder which just seems completely wrong to me. It will alter how all the built HttpClient works, and not just the one they will later be using in their Ribbon code in HttpClientRibbonConfiguration of Spring Cloud Netflix Ribbon. A potential bug in hiding? To me it seems like it, since it highly depends on calling order.
Does anyone have any ideas how something like this should be solved?
The easy alternative that I could do is to just not try and build upon the given HttpClientBuilder from Sleuth, but instead build a completely new one from the ground-up every time I need one, and check if a HttpTracing bean is available and use TracingHttpCientBuilder instead of HttpClientBuilder in that case, but this seems counter-intuitive.
I ran into the exact same problem. However, I had the option of defining my own HttpClientBuilder bean. I am not sure you are in the same position?
But by making the bean scope "prototype" a new bean instance is created every time it is injected somewhere. Then I could safely modify the HttpClientBuilder after injection.
#Bean
#Scope("prototype")
public HttpClientBuilder tracingHttpClientBuilder(..) {
...
}
While upgrading my Spring Boot applications through the 2.0.0 milestone releases, I've noticed that starting in 2.0.0.M4 security.require-ssl and other security configuration options are gone. I didn't find any mention of deprecations or a new approach in the current docs so I dug around and found the GitHub issue where the work originated. I applaud the goal in the GitHub issue to:
significantly simplify security configuration in 2.0.
and am happy change my patterns to upgrade, but I'm a little stuck on how to require SSL in specific environments. I know I can accomplish a similar outcome in my WebSecurityConfigurerAdapter configuration using http.requiresChannel().anyRequest().requiresSecure() but I don't want to enable this setting in every environment I run my applications in (e.g. pre-production environments without a certificate, local development on localhost). I know I could put some conditional logic in my WebSecurityConfigurerAdapter configuration but I like to keep my Spring configurations "environment agnostic" and keep my environment specific configurations in properties files specific to a profile.
After these recent simplifying changes to Spring Boot's security configuration, what's a recommended approach to require SSL in some environments?
There are a few options depending on your setup.
Changing the RequestMatcher
If the only time you require HTTPS is in an environment with a custom header injected by a Proxy (i.e. X-Forwarded-* headers), you can do something like this:
http
.requiresChannel()
.requestMatchers( r -> r.getHeader("X-Forwarded-Proto") != null).requiresSecure()
.and()
// ...
The nice thing about this approach is that you do not need to do anything to turn HTTPS on or off. The downside is that there is a very minimal performance hit of comparing the headers. This performance hit should be negligible, but may not be aesthetically pleasing to some.
Conditional Configuration
Since this is Java Code you can always have a boolean flag that determines if you require HTTPS or not. For example, create a member variable and resolve it to Externalized Configuration with something like this:
#Value("${security.require_ssl}")
private boolean requireHttps;
Then use something like this:
if(this.requireHttps) {
http
.requiresChannel()
.anyRequest().requiresSecure();
}
http
// ...
This approach aligns nicely with Spring Boot 1.x approach and it does not suffer from the additional if statement in each request. However, it requires a property to be managed.
Profiles
As mentioned by Madhura you can also use #Profile. I find this approach is better suited if you have lots of differences between environments and not as ideal for something minor like determining if HTTPS is required. The problem with this approach when making a small change is you run into a lot of duplication.
You're absolutely right about adding your own WebSecurityConfigurerAdapter for customizing security configuration. To keep that configuration environment agnostic, you can add an #Profile so that it can be switched on and off depending on the active profile. If it is only the ssl configuration that is environment agnostic, and the rest of the security configuration is the same for all environments, you can add a WebSecurityConfigurerAdapter that only configures http.requiresChannel().anyRequest().requiresSecure() that has the #Profile on it and order it such that it is the first one that kicks in.
For one of our projects, I should be able to call a webservice that uses WS-Security, i.e. the SOAP request should be signed with an X.509 certificate. I've been doing some tests to call the webservice through the use of the WebServiceRef annotation and I'm able to call the webservice without WS-Security.
So my question is: how can I activate and/or configure WS-Security when using the WebServiceRef annotation ?
Regards, Stefan Lecho.
If it still relevant, have a look at WSIT, and in particular, its WS-Security implementation described here. Basically you just have to use #WebServiceRef as you usually do, provide a wsit-client.xml, and specify the proper <Policy> node.
You might find these useful:
Implementing WS-Security with public key certificates for Metro-based web services
Configuring Keystores and Truststores