When using SSL, RabbitConnectionFactoryBean requires both keyStore and trustStore to be explicitly specified in the SSL properties. I'm looking for a way to work around this requirement when the server uses a well-known CA present in the default trustStore, since manually maintaining a separate JKS for this purpose becomes quite tedious.
Note: The Javadoc is clear on what needs to be overridden in order to modify the default behavior. However, I'm also using the Spring Boot autoconfiguration which is hardwired to use the default implementation.
Yes, that is too restrictive. I opened a JIRA Issue.
In the meantime, you can simply wire up your own
#Bean
public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config)
to override the default boot one; you'll still get the remaining boot autoconfig stuff.
Related
I have used Spring Rabbitmq XML configuration in my project. To create the RabbitConnectionFactoryBean, we provide the ssl.properties file resource with below properties
keyStore=file:/secret/keycert.p12
trustStore=file:/secret/trustStore
keyStore.passPhrase=secret
trustStore.passPhrase=secret
The passPhrases are hardcoded values. We are worried that any one who gains access to the system can read this file and misuse it. It is true that the system admin and OS should protect these files, but this can be considered a security threat when untrusted user logs in.
In this link Gary suggests to use Java configuration and we can use that to create the RabbitConnectionFactoryBean and maybe read the encrypted passwords from system and use the setter to set them in the bean.
But since we are already using XML configuration, is there any other ways to secure the passPhrases in the properties file?
Will this same configuration cause similar security issue in the PRODUCTION environment.?
Kindly help me on how to achieve security on the above.
Not sure if that is legal to say in the public, but I'll try.
There is some security token approach, when you start your project it requests such a token. An admin (or security representative) comes, inserts some special flesh drive, enter passwords. Your project reads properties from that device, populates all the properties and starts properly. That admin pulls flesh drive from USB and goes away. No one see password for your application!
The other solution you could consider is something like Config Server. So, your properties are stored somewhere outside of the current machine.
You also can really follow encryption way as well: http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/multi/multi__spring_cloud_context_application_context_services.html#_encryption_and_decryption
As far as I can tell, this is the process to create an HTTPS request using Indy:
Create a TIdHTTP object
Use a TIdSSLIOHandlerSocketOpenSSL object as its IOHandler
Set up this TIdSSLIOHandlerSocketOpenSSL object's SSLOptions and SSLContext to get the proper behaviour before starting the request
However, Indy's documentation is quite minimal as for the possible values for these two SSLOptions and SSLContext objects, even to achieve what seems to me to be pretty standard behaviour.
In particular, I would like to know how to do the following:
Validate the certificate against either (depending on what is more straightforward) :
The local system's trust store
A list of root certificates provided with the application
Drop the connection if the certificate has not been correctly validated.
It seems to me to be the most basic behaviour for an application that needs to call base once in a while: you want to make sure you're really speaking to your own back-end, but still leave you the possibility of changing CAs if you ever need it.
I guess the SSLContext's field rootCertFile should be used, however:
Nowhere is it said in what format the rootCertFile should be provided (pem? der? pkcs something?)
It is in no way obvious how one should process to configure several alternatives root certificates.
Can someone provide the method, and if possible, some sample code on how this behaviour can be achieved?
I want to enforce HTTPS for a Spring Boot application to be hosted at Pivotal CloudFoundry, and I think most of the applications would want this today. The common way of doing it, as I know, is using
http.requiresChannel().anyRequest().requiresSecure()
But this is causing a redirect loop. The cause, as I understand by refering to posts like this, is that the load balancer converts back https to http. That means, it has to be done at the load balancer level.
So, is there some option to tell CloudFoundry to enforce HTTPS for an application? If not, shouldn't this be a feature request? And, what could be a good way to have this today?
Update: Did any of you from Cloud Foundry or Spring Security team see this post? I think this is an essential feature before one can host an application on CloudFoundry. Googling, I found no easy solution but to tell the users to use https instead of http. But, even if I tell so, when an anonymous user tries to access a restricted page, Spring Security is redirecting him back, to the http login page.
Update 2: Of course, we have the x-forwarded-proto header as many answers suggest, but I don't know how hard it would be to customize the features of Spring Security to use that. Then, we have other things like Spring Social integrating with Spring Security, and I just faced an issue there as well. I think either Spring Security and tons of other other frameworks will need to come out with solutions to use x-forwarded-proto, or CloudFoundry needs to have some way to handle it transparently. I think the later would be far convenient.
Normally, when you push a WAR file to Cloud Foundry, the Java build pack will take that and deploy it to Tomcat. This works great because the Java build pack can configure Tomcat for you and automatically include a RemoteIpValve, which is what takes the x-forwarded-* headers and reconfigures your request object.
If you're using Spring Boot and pushing as a JAR file, you'll have an embed Tomcat in your application. Because Tomcat is embedded in your app, the Java build pack cannot configure it for the environment (i.e. it cannot configure the RemoteIpValve). This means you need to configure it. Instructions for doing that with Spring Boot can be found here.
If you're deploying an web application as a JAR file but using a different framework or embedded container, you'll need to look up the docs for your framework / container and see if it has automatic handling of the x-forwarded-* headers. If not, you'll need to manually handle that, like the other answers suggest.
You need to check the x-forwarded-proto header. Here is a method to do this.
public boolean isSecure (HttpServletRequest request) {
String protocol = request.getHeader("x-forwarded-proto");
if (protocol == null) {
return false;
}
else if (protocol.equals("https")) {
return true;
}
else {
return false;
}
}
Additionally, I have created an example servlet that does this as well.
https://hub.jazz.net/git/jsloyer/sslcheck
git clone https://hub.jazz.net/git/jsloyer/sslcheck
The app is running live at http://sslcheck.mybluemix.net and https://sslcheck.mybluemix.net.
Requests forwarded by the load balancer will have an http header called x-forwarded-proto set to https or http. You can use this to affect the behavior of your application with regard to SSL termination.
is it possible to configure the rapart tokn storage in wso2esb 4.8.0?
use case is this:
I have a SAML secured proxy, when the proxy is called, rampart stores the saml token in the token storage: SimpleTokenStore, (implementation of org.apache.rahas.TokenStorage).
It saves all the tokens in memory, so this becomes very heavy in a production environment.
My solution is to write an implementation of that interface, but my question is: where should I configure it?
thank you
Lorenzo
Solution is:
in the ws security policy file of the proxy service add in the <RampartConfig> element the child <tokenStoreClass>my.company.TokenStorageImplementation</tokenStoreClass>
then create a class that implements org.apache.rahas.TokenStorage, with custom business logic and put it in the carbon classpath eg: repository/components/lib
I think this is very usefull, because otherwise rampart save all received token in heap memory, so in a production environment this may cause Heap space saturation
hope it helps!
I have a Webapp that is secured using Spring Security CAS. The CAS Server and the Webapp sit behind a web server for reverse proxy (named url). The webapp uses ServiceAuthenticationDetailsSource to authenticate dynamic service urls. The problem I have is that Service Ticket validations are failing because the url supplied during validation does not match the url provided when the ticket was created. The set up works without the webserver when systems are connected using https://:/.
The issue seems to be that the web server modifies the HttpServletRequest when redirecting to the webapp where in it looses the "named url" information and is substituted with the and . The service ticket is obtained using the named url via "?service=" during login.
Any possible solution? Can apache reroute request without modifying it, especially for applications that are self identifying or for security reasons where CAS is trying to record the client IP address?
I have outlined a few options below:
Setup the Reverse Proxy
According to the Javadoc of ServletRequest: the HttpServletRequest.getServerName() will be:
the value of the part before ':' in the Host header value, if any, or
the resolved server name, or the server IP address.
This means you can configure your proxy to ensure the Host Header is set properly (Note Some containers like WebSphere do not honor the specification though).
Override using the Container Configuration
Many servers have a setup that can override this value in the event you are using a reverse proxy. There is a pretty decent thread on the Spring forums with a bit more information on it that I have summarized below.
If you are using Tomcat, I'd refer to the Reverse Proxy setup page. One method of configuration would be to configure the Http Connector to have the proxyName attribute to override the value returned by HttpServletRequest.getServerName() and proxyPort to override the value returned by HttpServletRequest.getServerPort(). An example configuration might look like:
server.xml
<Connector scheme="https" secure="true"
proxyPort="443" proxyName="example.com"
port="8009" protocol="AJP/1.3"
redirectPort="8443" maxThreads="750"
connectionTimeout="20000" />
Websphere has a few custom properties that do the same thing.
com.ibm.ws.webcontainer.extractHostHeaderPort = true
trusthostheaderport = true
httpsIndicatorHeader = com.ibm.ws.httpsIndicatorHeader
If you are not using either of these containers or need to support multiple domains, you will need to consult your containers documentation.
Custom AuthenticationDetailsSource
Of course Spring Security is pretty flexible, so you can always provide a custom implementation of AuthenticationDetailsSource that returns an instance of ServiceAuthenticationDetails that looks up the service URL in any way you wish.