Reputation: 21
I'm working on an application using Java EE, the Spring security framework and an Oracle 11g database. I need to add an MD5 hash into Spring security and I haven't succeeded with this.
What I have done so far:
1-In the first weeks I tried to add the md5 hash to my application without adding any code to springsecuritycontext.xml and I succeeded.
This is what I have done:
In the package called ma.dyaralmansour.zkgui.policy there are two classes.The first one is called PolicyManager and this class implements the spring-security UserDetailService. The second is called LoginLoggingPolicyService and this class is called from Spring AOP as an aspect and is for logging.
So this is what I have done:
*** I added an MD5Password class to the ma.dyaralmansour.zkgui.policy and I added some code to the PolicyManager class to activate the hash and it's working.
My problem now is:
All my passwords are hashed with an MD5 hash but I can't access the application anymore when I use the normal password.
Now I have 2 options, but I have no idea whatsoever how to implement them:
1- in the MD5password class there is a method named testPassword(String clearTextTestPassword,String encodedActualPassword)
It compares the normal password with the hashed one stored in the data base but I couldn't understand how to add it into my policymanager class.
2 - to completely remove all what I had done and only focus on the configuration of Spring security in order to hash the password and access to the application when I use a normal password.
Or is there an other solution?
http://www.mediafire.com/download/gxgda63wyhkpehn/DamPromoZK4.rar
<!-- Spring namespace-based configuration -->
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:zksp="http://www.zkoss.org/2008/zkspring"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- Enable the @Secured annotation to secure service layer methods -->
<global-method-security secured-annotations="enabled" />
<http auto-config="true">
<!-- ### If we have our own LoginPage. So we must ### -->
<!-- ### tell Spring the name and the place. ### -->
<!-- ### In our case we take the same page ### -->
<!-- ### for a error message by a failure. ### -->
<!-- ### Further the page after a successfully login. ### -->
<form-login login-page="/index.zul"
authentication-failure-url="/index.zul?login_error=1"
default-target-url="/AccueilIntranet.zul" />
<!-- ### Tell Spring where it goes after logout. ### -->
<!-- ### logout-url is a action url. ### -->
<logout logout-url="/j_spring_logout" logout-success-url="/index.zul" />
<!-- ### Define the pages that are to be intercepted ### -->
<!-- ### It is parsed from top to bottom. Means that ### -->
<!-- ### the most specific pattern is standing on TOP ### -->
<!-- ### and the CATCH ALL is on BOTTOM! ### -->
<intercept-url pattern="/pages/**" access="IS_AUTHENTICATED_REMEMBERED" filters="none" />
<intercept-url pattern="/WEB-INF/pages/**" access="IS_AUTHENTICATED_REMEMBERED" filters="none"/>
<!-- ### The root page is accessible by everyone but ### -->
<!-- ### internally spring makes a login and ### -->
<!-- ### this user becames a UserDetails ### -->
<!-- ### (in there are the ip-address and others) ### -->
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" filters="none"/>
<!-- ### Per user one session !! ### -->
<concurrent-session-control max-sessions="1" />
</http>
<!-- ### We define the kind of authentification with a ### -->
<!-- ### so called authentication-provider ### -->
<!-- ### So we have our users stored in a DB we use ### -->
<!-- ### our own user-service class and point to her. ### -->
<authentication-provider user-service-ref="myUserDetailsService">
</authentication-provider>
<!-- ### The Implementation of the Interface ### -->
<!-- ### UserDetailService for the logged in ### -->
<!-- ### user and his rights ### -->
<beans:bean id="myUserDetailsService" class="ma.dyaralmansour.zkgui.policy.PolicyManager">
<beans:property name="userService" ref="userService" />
</beans:bean>
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder hash="md5"/>
</authentication-provider>
<!-- ### This aspect call automatically the methode ### -->
<!-- ### 'loginLogging' which is for writing a log for ### -->
<!-- ### all successfully and failed logins, if a ### -->
<!-- ### methode is called that handles the ### -->
<!-- ### Authentication. ### -->
<beans:bean id="LoginLoggingPolicyService"
class="ma.dyaralmansour.zkgui.policy.LoginLoggingPolicyService">
<beans:property name="loginLoggingService" ref="loginLoggingService" />
</beans:bean>
<aop:config>
<aop:aspect id="LoginLoggingAspect" ref="LoginLoggingPolicyService">
<aop:pointcut id="authPointcut"
expression="execution(public org.springframework.security.Authentication org.springframework.security.providers.AuthenticationProvider.authenticate(org.springframework.security.Authentication))" />
<aop:around pointcut-ref="authPointcut" method="loginLogging" />
</aop:aspect>
</aop:config>
</beans:beans>
Upvotes: 1
Views: 16041
Reputation: 124431
Why are you reinventing the wheel? Spring Security supports password hashing out-of-the-box and it is simply a matter of configuration. Your custom implementation for the UserDetailService
must simply return the user found for the username (not check passwords or what so ever). Spring Security will then check the password with the configured hash.
Simply configure Spring Security appropriately by adding a password-encoder to your <authentication-provider .. >
element
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder hash="md5"/>
</authentication-provider>
You also might want to check the Spring Security documentation
Another suggestion for improvement is instead of using AOP for logging (assuming that is the only thing you do) implement an ApplicationListener
and listen for AbstractAuthenticationEvents. You might want to check the default LoggerListener for a simple working sample.
Upvotes: 3
Reputation: 48236
Use the new BCryptPasswordEncoder:
It will salt your passwords for you automatically.
I recommend BCrypt as it is strong, and slow, and has no known weaknesses. "Slowness" is actually a feature you want in a hashing algorithm, because that means it takes a longer time to crack if someone steals your passwords.
SHA 256 is weakened. MD5 is definitely broken.
Upvotes: 3