2

So I understand that you can check a password in Spring Security with salt based on a userDetail property and then hash it to compare to a hash in the database, however what if the salt used when creating each user is random (and is stored in the DB), would I need to create my own userDetails class that contains a salt property and then set that as the field spring security uses to salt with in the securityApplicationContext?

If so how would I go about writing my own userDetails class to accomplish that? Sorry still pretty new to Spring/Java.

Felix
  • 610
  • 2
  • 9
  • 21
  • 1
    The answer to your question is `Yes` if the salt is random then you would need to provide it to the verification process. Just write the `userDetails` class like any other class. – Security Hound May 16 '12 at 14:17
  • Ok but then how do I tell the securityApplicationContext to use myCustomUserDetails class to store the user instead of the default userDetails class? – Felix May 16 '12 at 14:30
  • You are better to use an algorithm like Bcrypt which includes a random salt. You'll find this kind of thing [has already been discussed before](http://stackoverflow.com/a/8662496/241990) if you search here and elsewhere online. – Shaun the Sheep May 16 '12 at 15:13
  • Unfortunately I'm bound in terms of password encryption. I need to integrate my app with another group's app which encrypts using random salt + hash. – Felix May 16 '12 at 15:18
  • The yes, as @Ramhound said, you'll need a salt value associated with each user. You will also have to implement a `PasswordEncoder` which matches the other group's algorithm. – Shaun the Sheep May 16 '12 at 21:19

1 Answers1

1

Ok but then how do I tell the securityApplicationContext to use myCustomUserDetails class to store the user instead of the default userDetails class?

Like this:

<b:bean id="customUserDetailsService" class="com.your.company.security.MyUserDetailsService"/>

<s:authentication-provider user-service-ref="customUserDetailsService" />

This goes in your security context.

Also this might help.

Writing a custom UserDetailsService.

Simeon
  • 7,582
  • 15
  • 64
  • 101
  • Ahh I saw this article while googling for an answer but I think I understand it better now. So just to make sure, I implement my own userDetailsService and within the 'loadByUsername' method I return a userDetails object that is my own implementation of userDetails, is that correct? – Felix May 17 '12 at 13:52
  • Yes. Exactly and then you inject your new `UserDetailsService`. – Simeon May 18 '12 at 07:11
  • Ok I got the CustomUserDetailsService and CustomUserDetails up, however when I try to login it says the username/password combination is incorrect. Not sure how to debug it though. How does SpringSecurity compare the inputted password to the DB one? I have the hash of the salted password as the password stored in the db. Would it have to do with the variable type? I get the salt and hash from the DB as byte[] and in CustomUserDetails I have: password = new String(myUser.getHash(), "UTF8"); salt = new String(myUser.getSalt(), "UTF8"); – Felix May 18 '12 at 16:02
  • You can do the authentication outside of the `UserDetailsService` and you should IMO. Your application can authenticate users by itself, it should not need spring security to do it. The idea of the user details service is to make spring "know about" the user in your system. So generally I'd create something like a `LoginService` and call it when the user tries to log in, rather than let the `UserDetailsService` know about passwords. The `UserDetailsService` should only return a user, by a given username, regardless of whether the user has logged in or not. – Simeon May 19 '12 at 06:46
  • Another thing, don't ever user `new String()` this is why: http://stackoverflow.com/questions/2009228/strings-are-objects-in-java-so-why-dont-we-use-new-to-create-them – Simeon May 19 '12 at 06:47
  • Thanks Simeon, copied that from a solution on another forum. I got the problem figured out, but it may not be the right solution. I was storing hash and salt as byte[] but then when I queried from the DB, the salt.toString() always gave something different on different queries, so I had to store the salt/hash as a string in the DB, doing it that way works if I query them out as a String. – Felix May 22 '12 at 16:56