Separate Keystore for Spring-WS SSL handshake and Message Encryption - ssl

I have a question in regards to
SSLHandshakeException talking to a https Web service using Spring WebServiceTemplate
answerd by borodark
"No need to import keys into keystore."
If we dont provide a keystore then what will Httpclient use for sending the Client certificate for SSL handshake ?
I have a requirement to invoke web services on a bussiness partner -
a) Authenticate using SSL using a public key certificate X
b) Encrypt and Sign SOAP messages using public key certificate Y
I guess I will need to specify certificate Y to the following :
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="securementActions" value="Signature"/>
<property name="securementSignatureKeyIdentifier" value="DirectReference"/>
<property name="securementUsername" value="mycert"/>
<property name="securementPassword" value="certpass"/>
<property name="securementSignatureCrypto">
<bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
<property name="keyStorePassword" value="123456"/>
<property name="keyStoreLocation" value="classpath:/keystore.jks"/>
</bean>
</property>
</bean>
I am not sure how/where to specify certificate X for SSL handshake. I think its the HttpClient but I dont see it in the XML posted by borodark.
Please help !

in the xml file where you have configured the keystore you should have something like this:
<beans>
<bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
<property name="keyStore" ref="keyStore"/>
<property name="privateKeyPassword" value="changeit"/>
</bean>
<bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
<property name="location" value="classpath:keystore.jks"/>
<property name="password" value="changeit"/>
</bean>
</beans>
the cue here is
<property name="location" value="classpath:keystore.jks"/>
that is the path to the keystore.. now, possibly you can use a certain alias inside the keystore for ssl handhshake (and that's what you configure here), additionally the security policy leverages on the same file, but then again in the securitypolicy file you can specify a different alias.. and that should do the trick..
Consider that while
<property name="location" value="classpath:keystore.jks"/>
indicates classpath you can use other form to reference resources outside the war itself, and that lets you change the certificate without touching the war at all..

Related

Storing keyStorePassword value encrypted in SSL configuration XML

Do I have a way to store keyStorePassword and trustStorePassword values encrypted in Ignite SSL configuration XML instead of plain text?
<property name="sslContextFactory">
<bean class="org.apache.ignite.ssl.SslContextFactory">
<property name="keyStoreFilePath" value="keystore/node.jks"/>
<property name="keyStorePassword" value="123456"/>
<property name="trustStoreFilePath" value="keystore/trust.jks"/>
<property name="trustStorePassword" value="123456"/>
<property name="protocol" value="TLSv1.3"/>
</bean>
</property>
Thanks
Stanislav
The simplest way is probably to use property palceholders (Ignite’s XML file is just Spring).
You can also configure it to pull passwords from secret stores. Blog here.

LDAP authentication with Apache Nifi not working

I have been working on this problem for quite some time and I would like answers and suggestions from you guys on the issue I am facing. I am trying to get my Nifi standalone instance on my VM, which is in my company's network, authenticated using the ldap-provider in login-identity-providers.xml. I input all the required values except for the truststores and keystores because the company has an LDAP and not LDAPS . So, I figured I wouldn't need those certificates. I have set the initial admin identity in the authorizers.xml too. And, of course, set the https port and host(0.0.0.0). But, when I try to run and call the server from the browser using the url, the Site can't be reached , ERR_CONNECTION_REFUSED pops up. Basically, can't reach the server. I have checked the DN, LDAP url and other properties to be correct and working when I queried through ldapsearch.
So, is it because I don't specify the truststore and keystore in the configuration? If so, do i need to manually create these certs for each client that wish to access Nifi. I thought the LDAP certificate would be enough for a person to authenticate to Nifi. Please advise me on how to go about getting the CA for truststore, server and client certificates for the employees to use Nifi through LDAP.
My ldap-provider looks like this(scrubbed) :
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">SIMPLE</property>
<property name="Manager DN">cn=user-name,ou=Accounts,dc=domain,dc=company-name,dc=com</property>
<property name="Manager Password">My-account-password</property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password"></property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password"></property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol">TLS</property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">IGNORE</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url">the-ldap-url-of-company</property>
<property name="User Search Base">cn=Users,ou=Accounts,dc=corp,dc=company-name,dc=com</property>
<property name="User Search Filter">sAMAccountName={0}</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
Nifi version - 1.0.0
Running in a Ubuntu Trusty VM.
When using LDAP authentication you should reach a login page for NiFi where you supply the username and password to authenticate against LDAP. Since you are not even reaching that page, something else is wrong before it is even getting to the LDAP part.
Some things to check...
In NiFi properties the active identity provider should be set with the following property:
nifi.security.user.login.identity.provider=ldap-provider
When you are using any kind of authentication NiFi must be configured to use https which requires providing the following configuration:
nifi.web.https.host=
nifi.web.https.port=
nifi.security.keystore=
nifi.security.keystoreType=
nifi.security.keystorePasswd=
nifi.security.keyPasswd=
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.trustStorePassword=
The hostname that you set in nifi.web.https.host should also line up with the hostname of the certificate being used for the nifi.security.keystore. I have a feeling that setting the https host to 0.0.0.0 is not what you want, but I'm not totally sure what that does.
Once you get the https configuration correct, then you should reach the login page when going to https://yourhost:post/nifi and after that is where your LDAP configuration will come into play.

Disabling ssl v3 in activemq admin console

How to disable ssl v3 in activemq Admin console (port 8161)? I did not found any document on line.
In my jetty.xml file I can see below lines:
<bean id="SecureConnector" class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<property name="port" value="8161" />
<property name="keystore" value="file:${activemq.conf}/broker.ks" />
<property name="password" value="password" />
</bean>
ActiveMQ uses a basic spring wired jetty server for the admin web-gui. Use the methods available in Jetty documentation - or look at this SO.
SslSelectChannelConnector takes a SslContextFactory as constructor arg. That factory has a excludeProtocols property which you can feed with "sslv3".
Wire that up in spring should be straight forward.

spring-security : Using user's certificate to authenticate against LDAP

I managed to authentify the user against the Ldap using the username found in the certificate. What I would like to obtain is to authentify the user using directly the certificate on the Ldap.
I cannot found how to pass the certificate to the Ldap.
here is the current config (using the certificate's username) :
<security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>
<bean name="userService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="ldapUserSearch"/>
<constructor-arg ref="ldapAuthoritiesPopulator"/>
</bean>
<bean name="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg value=""/>
<constructor-arg value="sAMAccountName={0}"/>
<constructor-arg ref="contextSource" />
</bean>
<bean name="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource" />
<constructor-arg value="" />
<property name="groupSearchFilter" value="member={0}" />
<property name="searchSubtree" value="true" />
</bean>
I was looking in to this issue myself. I have yet to find an authentication stack that does X509->account resolution "right". I got hung up on the fact that Spring Security's UserDetailsService interface insists on a string uid for lookup, but in many cases it is impossible to derive such a UID from the information contained in an X509 certificate's subject (e.g. there are many cn=John Smith in the world, or even within a single organization, nor is email required in a certificate DN). The uniqueness of a certificate lies in the Issuer + Serial Number combination, not the Subject.
After looking through the API there are a couple ways to go about this. Either way probably precludes using the namespace and setting up the filter chain and beans yourself:
1) Implement your own AuthenticationUserDetailsService and bind this to the PreAuthenticatedAuthenticationProvider. By default, I believe, the namespace sets up a UserDetailsByNameServiceWrapper using the passed-in user-service-ref. Going this route means you have to do everything to set up the UserDetails, including granted authorities resolution. Of course you can delegate all this, but its more work.
2) If your LDAP store is keyed by some UID, and this is the route I am leaning towards, implement your own X509PrincipalExtractor and bind it to the X509AuthenticationFilter and return the string uid that your LDAPUserDetailsService is configured to expect. Within the extractor implement the logic to search your LDAP store for the stored certificate. I do not know of any strategies that will work across LDAP servers, the easiest way would be if your LDAP supports RFC4523 certificateMatch or certificateExactMatch and you can configure a search filter that will return you a unique account from which you can then return the attribute you need (e.g. sAMAccountName). If not, if your certificates contain a value that you can filter on (e.g. certificate cn = LDAP cn) that you can use to retrieve a candidate set of LDAP results for, extract their certificates to X509Certificate and do .equals() against the passed in certificate to find the account that matches and return its uid.
Set up the LDAP server to use SSL with client authentication.
Finally, I've implemented the following sollution in my NON-web application :
<bean id="x509ContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://hostname:389/DC=base,DC=com" />
<property name="authenticationStrategy">
<bean class="org.springframework.ldap.core.support.ExternalTlsDirContextAuthenticationStrategy">
<property name="sslSocketFactory">
<bean class="yourOwnSocketFactory"/>
</property>
<property name="shutdownTlsGracefully" value="true" />
</bean>
</property>
</bean>
where yourOwnSocketFactory takes the user's certificate to establish the TLS connection.
A successfull TLS connection means the user is authenticated. That's the case with a well configured LDAP, which should check the user including certificate revokation list.
Once the connection established, you have to recover the user's informations with a custom BindAuthenticator which could extract (X509PrincipalExtractor) Certificate DN (or other usefull info) to match the LDAP user.

Difference between Tomcat and JBoss in context of "Spring Security framework" deployment

I have an application that use Spring-Security framework with Jboss Server. Everything works fine. I can get account locked, bad credentials messages based on the authentication.
Now, I'm trying to move to configure the same thing with Tomcat. But, I don't get account locked, bad credentials messages. I just get "Unauthorized" for every wrong authentication. Can some body point me to What I am missing ? Here is the securitycontext.xml file content:
<bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="basicAuthenticationEntryPoint"/>
</bean>
<bean id="filterInvocationInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager">
</property>
</bean>
<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
<property name="providers">
<list>
<ref local="jaasAuthenticationProvider"/>
<ref local="casAuthenticationProvider"/>
</list>
</property>
</bean>