Spring Security - Alter username on the way in - spring

I have a database where passwords are encrypted in plain old md5. There is no salt. All the usernames are numeric.
This is what the db looks like..
Username, Password, Hashed Password
0101,abcd123,79cfeb94595de33b3326c06ab1c7dbda
I am writing a web application using spring security. I have managed to get authentication working when the user the user types in 0101 as the username and then abcd123 as the password.
But what I really want working is the user to type in 101 (without the leading zero) as the username and abcd123 as the password.
I got my code working with the leading zero by overriding org.springframework.security.core.userdetails.UserDetailsService > loadUserByUsername(String userId).
I started looking at salt and then realized that I was totally going down the wrong track because this has nothing to do with my use password.
How can I alter my code so that my requirement is meant? I tried to hack my own implementation of loadUserByUsername(String userId) to prepend a 0 on the way into the method but this did not work.
thanks

Thanks for the advice guys. I was lucky and I found another column in the database named sign on id. It contains the actual string that the user enters to sign into the application.

Related

Spring Security 5 programatically validate a username and password

I have a grails 5 Spring Security app (that i've recently migrated from grails 3). Spring Security 4+ uses a different password scheme where it includes the algorithm, salt and hashed password all in the password field delimited like so: "{algorithm}{salt}{hash}"
This all works fine. I've appended "{SHA-256}" to the start of existing passwords, and authentication is working for the web app.
The problem is that I have an API section of my app that uses basic auth which I manually authenticate in my controllers (not using spring security). This is simple and stateless and works well for my purposes. Problem is, I can no longer validate usernames and passwords when I create new users which Spring Security adds a salt for.
Old code that worked before adding salt to new users was effectively:
String sha256hex = DigestUtils.sha256Hex(password);
String dbHashedPw = "{SHA-256}${sha256hex}"
user = User.findByUsernameAndPassword(email, dbHashedPw)
This doesn't handle salt, or iterations, so does not work on passwords generated for new users.
I've tried enabling grails.plugin.springsecurity.useBasicAuth: true (in application.yml) but this perhaps was misconfigured since it seemed to have no effect.
I've also tried improving my code above to work with the salt and iterating in the same manner as Spring Security does, but it becomes complicated and doesn't seem like the best way to do it.
What I want is an interface like:
boolean springSecurityService.validatePassword(UserDetails userDetails, String password)
Where Spring Security would grab the password from the database and use the markup describing the algorithm and the salt, and do the appropriate hashing on password and compare the two, returning a boolean if the password matches.
It seems like this should be simple, but I've now spent over a full day hacking around it with no success. Any help would be appreciated!
Answering my own question with a workaround I've found. I couldn't find the springSecurityService interface that I wanted, but I did find I could emulate the old grails 3 password encoding by not calling spring security in User.groovy, and instead doing the following:
import org.apache.commons.codec.digest.DigestUtils
...
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = "{SHA-256}" + DigestUtils.sha256Hex(password)
}
Note I'm relying on apache library: 'commons-codec:commons-codec:1.11' to do the hash.
Of course, it should be mentioned that SHA-256 is not considered secure any more and this is only for backwards compatibility before a migration is possible.

Get the password after encoded by PasswordEncoder and generated with jwt in spring boot security

I'm working with Spring Boot Security.
I have to Sign up a user (name, login, password, ... .),
the password inserted to oracle DB is encoded using PasswordEncoder.
Then the Sign in is implemented with JWT.
I'd like to recuperate the password registered in DB, but it's not possible with PasswordEncoder.
That's why I used StandardPBEStringEncryptor which allowed decrypt the encrypted registered password.
But, now, I faced another problem which is :
encoded password does not look like bcrypt jwt
Could you please tell me if I missed something ? Have you any idea to recuperate the registered password ?
Any suggestion will be appreciated.

Getting username in PasswordEncoder

I created my own authentication provider for my spring application, on which I specified the org.springframework.security.crypto.password.PasswordEncoder. I have my users stored in the database with their encrypted passwords (after a database algorithm). For being able to make the authentication, I would need to have access from the org.springframework.security.crypto.password.PasswordEncoder class to the username that is sent for authentication. Can anyone guide me how can I do this? Or is there any other approach?
N.B. I'm using SpringSecurity 3.2.
I don't even care if it's an old question, I've just spent 9 hours trying to figure this out. Might as well leave it here in case someone else stumbles upon this again.
String username = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest().getParameter("username");
Using the code above I was able to extract the username from current request.
ATTENTION: You must use the following class org.springframework.web.context.request.RequestContextHolder
There was a similar one that was doing me wrong.
Assuming that User Entered UserName,UserPassword is User,Pwd.
In order to Authenticate, you can perform the following.
Get User Entered Username and Password(User,Pwd).
Encode the Pwd using
String encodedPassword=passwordEncoder.encode(pwd);
Compare if UserEnteredUserName=DBUserNAme and UserEnteredEncodedPassword==EncodedPasswordInDB, based on match values, you can authenticate the User.

Unable to decrypt password in Jhipster

I have working on jhipster.but i am unable to decrypt password in jhipster and Spring.PasswordEncoderClass only provide encode and Match password function.can you help to decrypt password in jhipster.
Thanks in advance
We are using Spring Security's StandardPasswordEncoder, I do hope you can't decrypt it :-)
We are indeed storing hashed passwords: as you say, you can encode a password, and validate (match) if a specific String is the correct password, but you can't decrypt it. This means that if your database is stolen by a hacker, he would have a very hard time to figure out your users' passwords.
So this is a very good idea if you want to keep your users' password secure.
If, however, you want to have your passwords in plain text, you can change the encoder in your SecurityConfiguration class: you need to change the "passwordEncoder" bean, and probably use Spring Security's "NoOpPasswordEncoder" class. Of course, I have never done it, as I care about my users' data :-)

Spring PasswordEncoder decoding in external application

I need to decode a password that was encoded using the org.springframework.security.authentication.encoding.PasswordEncoder.encodePassword method. Basically, application "A" maintains the encoded/encrypted password in its database. Application "B" makes a RESTful call to application "A" to get the userid and password (passes password as encoded/encrypted) and then application "B" needs to view the clear text version of the password, how would it decode it?
The mentioned class "org.springframework.security.authentication.encoding.PasswordEncoder.encodePassword" seems to use digest function to encode the password. Because all the digest function are mentioned to be one way only it is easy to make encoded password from the clear text but almost impossible to obtain unencrypted version from the digest.
If you want to authenticate user just encrypt the password and compare it to it's stored encrypted version.
Other option can be reseting the password (replacing value stored in application "A").
If you insist on unencrypted password in application "B" from the digest, you have to crack it, which can be time consuming operation...

Resources