LDAP authentication on Apache against hashed password - java

I have a setup with an apache HTTP server front facing tomcat server. The Apache server uses LDAP for authentication.
I am using an Embedded LDAP server (Apache DS) and have configured to disable anonymous bind using
service.setAllowAnonymousAccess(false); // Disable Anonymous Access
service.setAccessControlEnabled(true); // Enable basic access control check (allow only System Admin to login to LDAP Server)
My application uses Spring LDAP to connect and perform user operations like Adding a user. I have configured it in spring.xml as follows:
<bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://localhost:389" />
<property name="base" value="dc=test,dc=com" />
<property name="userDn" value="uid=admin,ou=system" />
<property name="password" value="secret" />
</bean>
Apache httpd.conf is configured to use basic auth
AuthLDAPBindDN "uid=admin,ou=system"
AuthLDAPBindPassword "{SHA}<Hash for secret>"
ISSUE 1 : When trying to login to ldap server using a client (say jexplorer), I am able to login using both Hashed password and using the plain text "secret". How is that possible?
In this case , if someone gets to know the AuthLDAPBindDN and AuthLDAPBindPassword which is a hashed one in my case, They will be able to login using the same to the LDAP server with full access which is a security threat.
Also, I want to replace the password in spring.xml with a hashed one. Since, admin can change the LDAP password, How do I ensure my application to use the updated hashed password as we are hard-coding it in spring.xml?

With regards to your second question: you should typically never hardcode stuff like server URLs, user names, passwords, etc in your XML file. These things should typically be externalized to a property file and processed using <context:property-placeholder>. Say, for instance, that you have a property file with the following contents:
ldap.server.url=ldap://localhost:389
ldap.base=dc=test,dc=com
ldap.userDn=uid=admin,ou=system
ldap.password=secret
You can then refer to these properties in your configuration file, e.g.:
<context:property-placeholder ignore-resource-not-found="true"
location="classpath:/ldap.properties,
file:/etc/mysystem/ldap.properties" />
<bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="${ldap.server.url}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="${ldap.userDn}" />
<property name="password" value="${ldap.password}" />
</bean>
Spring will automatically replace the stuff within ${} with the corresponding values from your properties file.
Note that I specified two property file locations in the <context:property-placeholder> element, and that I also included ignore-resource-not-found="true". This is useful, because it enables you to include a properties file with your source for simple development setup, but in production, if you place a properties file under /etc/mysystem/ldap.properties, this will override the stuff in the bundled properties file.
This way, if the password is changed by admin in production environment, all you need to do is change the properties file; you don't need to rebuild the application.
With regards to why the apache DS accepts the hashed password; one reason might be that your LDAP server is set up to accept anonymous access for read operation, which means that it actually doesn't authenticate at all when you're just reading. Might be something else though, you'll have to direct the question to Apache DS support.

Related

How to configuration of IDP metadata and SP metadata in Spring Security SAML sample?

I want to deal with Spring Security SAML. For this, I start to explore Spring Security SAML. At the beginning, I create an account at SSOCircle. Than I configurated of IDP metadata and generation of SP metadata (4.2.2 and 4.2.3). At entityId I set:
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="http://idp.ssocircle.com"/>
</bean>
</constructor-arg>
</bean>
When I start application, I have:
Error occurred:
Reason: Unable to do Single Sign On or Federation.
or
Error occurred:
Reason: Unable to get AuthnRequest.
How to configure Spring Security SAML?
Follow the steps in the QuickStart chapter. Some differences to note:
Sign up at http://www.ssocircle.com/. You need to verify your email address.
The metadataGeneratorFilter section of sample/src/main/webapp/WEB-INF/securityContext.xml should look like this (Note: signMetadata property is commented out):
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="urn:test:YourName:YourCity"/>
<!--<property name="signMetadata" value="false"/>-->
</bean>
</constructor-arg>
Build and start the web server locally. Then download the metadata at http://localhost:8080/spring-security-saml2-sample/saml/metadata. Copy the contents to your clipboard.
Update the metadata of your new profile at https://idp.ssocircle.com/sso/hos/ManageSPMetadata.jsp.
Enter the FQDN of the service as "urn:test:YourName:YourCity". You need to enter unique values for Your Name and Your City. Paste in the metadata from above.
To Test:
Logout of SSO Circle Service.
Go to http://localhost:8080/spring-security-saml2-sample
You should be redirected to the SSO Circle login.
Login with your SSO Circle credentials.
You should be redirected to your local service provider page and authenticated.
The metadata generator filter generates metadata for your application (service provider). The entity id you're providing (http://idp.ssocircle.com) is already used by the SSO Circle, you should create a unique value which describes your application, e.g. urn:test:helsinki:myapp
Just like the manual says:
make sure to replace the entityId value with a string which is unique
within the SSO Circle service (e.g. urn:test:yourname:yourcity)

How to access multiple remote redis with JedisConnectionFactory?

I made a manager/Service Server system.
Manager server collects data from database and send that data to multiple Service servers.
My code works nice when I have only 1 server. My configuration like below.(root-context.xml)
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="127.0.0.1"/>
<property name="port" value="6379"/>
</bean>
The Problem is Service servers should be multiple. Is there any way to set multiple connection list with spring configurations? Thanks:D
P.S
I know the way to use JedisHelper.java which can be found easily in github. However, what I want to do is figure this out in spring root-context.xml.
you need to use a Jedis Pool.
http://docs.spring.io/spring-data/redis/docs/1.0.6.RELEASE/api/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.html
You need to specify a pool and set it up with all your servers.

What is the recommended way to store user credentials in spring MVC?

I am creating a Spring MVC application which is a SOAP client. To communicate with SOAP web-service I am suppose to pass the login credentials. My application doesn't need to store any details dynamically and hence I am not using any db for this application. So kindly suggest a recommended practice to store the sensitive credential for my application. This credential will we managed by the system admin and must be easy for him to change according to the requirement.
Thanks in advance.
Store the username and password in a properties file external to your webapp spring context. That way the sysadmin can easily lock down read access on the properties file to the relevant parties (e.g. your application and himself). That should stop prying eyes seeing the password.
In your spring context have something like:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<list>
<value>/path/to/config.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean id="myBean" class="...">
<property name="username" value="{usernameFromExternalPropFile}" />
<property name="password" value="{passwordFromExternalPropFile}" />
</bean>
The sysadmin will then also be able to change the username/password independently from a build.
See http://www.javaworld.com/community/node/8309/
The simplest option would be to store them in your application context XML configuration file as properties to the bean which is communicating with the SOAP webservice.

passwordCallback in CXF

I develop a webservice client for an existing webservice. I am using Apache CXF 2.2. The service requires security with Username and plain text password, which I configured like this:
<bean id="myPasswordCallback"
class="com.kraemer_imd.mobilized.m2m_adapter.ClientPasswordCallback"/>
<jaxws:client id="m2mClientService"
serviceClass="de.vodafone.easypu.ws.EasyPUOrderServicePortType"
address="http://m2m.vodafone.de/speasy/services/EasyPUOrderService"
bindingId="http://www.w3.org/2003/05/soap/bindings/HTTP/">
<jaxws:outInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken Timestamp"/>
<entry key="passwordType" value="PasswordText"/>
<entry key="user" value="myusername"/>
<entry key="passwordCallbackRef">
<ref bean="myPasswordCallback"/>
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
That works quite well. But I did not understand why I have to provide the password via a callback handler instead of just providing it via configuration. The documentation says it is for security reasons, but I donĀ“t see why this should be more secure to have a callback handler that reads it from a property file (or worse has it hard coded in the callback).
So, could somebody explain this to me? Maybe the callback is intended for some magic stuff that I missed..
Thanks
Michel
The password callback is provided by Apache CXF as a mechanism for the client application to retrieve the credentials for the targeted webservice, which at runtime is likely to be stored in the database, configuration fiels, LDAP or some other store. This callback hook provides the flexibility to the application to retrieve the credentials from application specific configuration.
If password is stored in clear text in the configuration then this approach may not give you any extra security.
However having password stored as clear text in some configuration may have some security issues as there can be folks that may need access to this configuration and will be able to hold of password although it may not have been intended to.
Better is to store the encrypted password in the configuration. In this case, you need some code that will decrypt this password before it's use. Password callback will come to rescue in this scenario.

WebSphere and PropertyPlaceholderConfigurer

I'm a big user of properties (with PropertyPlaceholderConfigurer) for making my application as "dynamic" as possible. Almost all the constants are defined as such. Anyway, I'm currently defining a default.properties which comes shipped with the default WAR.
In other environments (Acceptance/Production) I need to overwrite of the configurations. I'm doing this as following:
<bean id="propertyManager"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:com/company/default.properties</value>
<value>file:${COMPANY_PROPERTIES_LOCATION}\kbo-select-settings.properties</value>
</list>
</property>
</bean>
With this means I can use a promotable build for each of the environments.
HOWEVER, I do dislike the fact that I can't change any of my properties from inside WebSphere. Instead I have to go to each of the servers (we have 8 clustered) and change the properties accordingly. It would be a lot more user friendly if I could change those from inside WebSphere and just perform a restart afterwards...
Anyone has an idea on how I could do such a promotable build? I already define JNDI configuration for datasources/java mail/etc.
Thanks!
We solved this problem by using an extension on the property file for each environment (local, dev, int, tst ...) and each file contained specific values for those environments. The only addition you then require is a VM argument on the server to set -Druntime.env=X.
Your lookups in your config file will then look like this
<bean id="propertyManager"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:com/company/default.properties.${runtime.env}</value>
<value>file:${COMPANY_PROPERTIES_LOCATION}\kbo-select-settings.properties</value>
</list>
</property>
</bean>
Of course this only works if you have fairly static environments, as it still doesn't lend itself to changing it at runtime, but it does makes promotion of the application dead simple. If you want to be able to change the values without redeploying your application, you will have to have them stored outside your application, which you already seem to be doing for the kbo-select-settings.properties
One potential issue is that you are hardcoding the location of your properties file. You could specify the location of the properties file as a JNDI resource and falling back on the defaults specified on the classpath:
<!-- try to lookup the configuration from a URL, if that doesn't work, fall back to the properties on the classpath -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<bean class="org.springframework.core.io.UrlResource">
<constructor-arg>
<jee:jndi-lookup
jndi-name="url/config"
default-value="file:///tmp" /> <!-- dummy default value ensures that the URL lookup doesn't fall over if the JNDI resource isn't defined -->
</constructor-arg>
</bean>
</property>
<property name="properties">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:com/company/default.properties</value>
</list>
</property>
</bean>
</property>
<property name="ignoreResourceNotFound" value="true"/>
</bean>
That way you can specify different file names for different environments using the WAS console in Resources > URL > URLs by creating a resource with the JNDI-name "url/config" and pointing it to the correct file (file:///your/path/to/properties).
As an alternative solution, if you want to manage individual properties through the console, you instead of using the PropertyPlaceholderConfigurer you could use jee:jndi-lookup to get values from the web.xml env-entries (which you can manage using the WAS console). See this answer
If the configuration is in the EAR file then I know of no simple way to propogate changes without backdoor cheats or re-deploying the app.
I think that configuration, espcially that which changes when you promote the app should not be in the application.
One approach is described here by Keys Botzum,
Note that you can actually propogate files that are not part of any particular application out to nodes using standard WebSphere synchronisation.
Another option is to use a database for config. These days poppin XML into a DB such as DB2 is not very hard.
Adding a URL resource that points to your config files to your websphere servers and then looking that up in your application is a viable way to go. You can then configure the url to point to a central location where all the configuration files are managed - if you use svn and your svn has read-only access you could even directly read them from svn (via http).
Spring has some built in facilities for this, and it also means you can priorities various config files.
For more information take a look at how-to-differentiate-between-test-and-production-properties-in-an-application
The way that I have dealt with this is to use property values on the JVM's but then reference them to a WebSphere variable that is defined at the cluser or cell level. For example, say you want a value called value1 set in param1 in your spring configuration you would do the following:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
And then something like as follows do reference the variable:
<bean id="id" class="com.blah.class">
<property name="value1" value="${param1}" />
</bean>
Then within your tests you can setup your tests as follows:
/**
* #see org.springframework.test.AbstractSingleSpringContextTests#prepareApplicationContext(org.springframework.context.support.GenericApplicationContext)
*/
#Override
protected void prepareApplicationContext(GenericApplicationContext context) {
System.setProperty("param1", "myvalue");
}
Then from within the websphere configuration, if you create a JVM variable and link it to the WebSphere variable you only need to change the WebSphere variable and it will automatically update all the JVM variables on each machine.
To do this, create a JVM variable called:
param1
with a value of ${webspherevar.param1}
And then create a WebSphere variable called:
webspherevar.param1
That contains whatever the value you need to put in it. This allows you to then not have to ship around the values for each environment and they can be instead loaded into the environment and just used.
I hope this helps.

Categories