My web app is using Spring Security plugin for authentication and authorization. I'm building sort of an API, where I need to verify user password.
Spring Security is configured to use BCrypt with 5 logrounds and username property as salt:
grails.plugins.springsecurity.password.algorithm = 'brcypt'
grails.plugins.springsecurity.password.bcrypt.logrounds = 5
grails.plugins.springsecurity.dao.reflectionSaltSourceProperty = 'username' // password salting
Now, in my controller I'd like to verify user password and login. For this, I call springSecurityService.encodePassword(cmd.password, cmd.username)
where cmd is command object with my params. The thing is, on each request, password encoded with springSecurityService is different and never the same as user password in databse. I tried also with constant values in encodePassword call, something like this:
springSecurityService.encodePassword('foo', 'bar') and result is the same: on each request encoded password is different. This way I can't verify user password and get valid user instance from databse.
Any ideas how to solve this?
bcrypt generates a uniq salt each time, and includes it into result hash. Because of it springSecurityService.encodePasswod just ignores second argument, and reflectionSaltSourceProperty option as well (see sources). So, each time you'll get different hash for same input data.
You can use BCrypt class to validate password, like:
if (BCrypt.checkpw(candidate_password, stored_hash))
System.out.println("It matches");
else
System.out.println("It does not match");
See docs for BCrypt: http://static.springsource.org/autorepo/docs/spring-security/3.1.x/apidocs/org/springframework/security/crypto/bcrypt/BCrypt.html
Btw, as you're using Spring Security, it's already implemented in framework, so you can use passwordEncoder bean:
def passwrodEncoder
...
passwordEncoder.isPasswordValid(user.password, cmd.password, user.username) //user.username will be ignored
Related
I would like to store and validate passwords in a ruby application that does not use devise, and have them be compatible with a future application that does use devise. What is the default password hashing scheme that devise uses, and is it possible to extract and use just this component from devise?
Devise's DatabaseAuthenticatable module uses BCrpyt to hash passwords, wrapped up in the Devise::Encryptor module. The relevant method, digest, is pretty simple:
def self.digest(klass, password)
if klass.pepper.present?
password = "#{password}#{klass.pepper}"
end
::BCrypt::Password.create(password, cost: klass.stretches).to_s
end
klass is only used to fetch a couple parameters: pepper, a string which is appended onto the password pre-hashing but not stored in the database (unlike salt, which is appended as well but stored with the password in the DB); and cost, a measure of how secure the hash should be (see the docs). Both of these are static and you can hard-code them into your non-Devise app (but make sure to keep pepper secret!).
So, your hash method might be written just as:
def self.digest(password)
password = "#{password}#{ENV['PASSWORD_PEPPER']}"
::BCrypt::Password.create(password, cost: 10).to_s
end
In radcheck table of freeradius mysql database, I can add few type of password.
For crypt password, where can I store the salt?
Usually the salt is prepended to the hash automatically by the crypt function, so you don't need to store it separately.
If you want everything to 'just work', you should be able to use the following format:
Password-With-Header := '{crypt}<crypt output>'
Then:
authorize {
sql
pap
}
Basically as the question asks.
The AuthLogic documentation for verify_password_method states:
The name of the method in your model used to verify the password. This should be an instance method. It should also be prepared to accept a raw password and a crytped password.
I'd like to support this, because it allows me to maintain our system's current masquerading behaviour without storing plain-text passwords like we have been in the past. However, it seems to me like allowing a simple string comparison to the crypted_password in the database is just as bad as storing the regular plain-text passwords.
Am I missing something here, or is there some other way to accept a crypted password in AuthLogic?
For reference, this is how I was going to write the valid_password? method:
def valid_password?(password, check_from_database = nil)
if password == self.crypted_password
true
else
super(password, check_from_database)
end
end
Ok, turns out that there's a much easier way to do this (although it seems horribly undocumented, and didn't turn up with a Google search of how to achieve this).
Authlogic::Session::Base.new(#user, true)
That line allows session creation without checking credentials. Obviously you should be careful with this since it assumes that the user has already identified themselves correctly - for my usage, since there is a check to ensure the current user is the admin user, it's safe.
I've got a cross-website integration to handle. Basically I'm passing a param into the rails application and if it evaluates correctly ... then I'd like to log a user in.
Can this be done without the users password?
something like simply evaluating the password as true?
This is called "token authentication" and is supported by Devise, or can be relatively easily ginned up on your own. You want to generate a non-guessable secret token (your param), and then use that in lieu of a username. The devise wiki has links to a couple of examples:
https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
If you want a lighter-weight solution, you can also simply generate an auth token (using something like bcrypt) and then do something like:
#user = User.find_by_auth_token(params[:auth_token])
if #user is nil, then return a 403.
In my Rails app, I periodically require the user to re-enter their password after a certain amount of inactivity--like with sudo on Linux. My app uses Authlogic for authentication and handling password storage and encryption.
I need some method to encrypt the password the user enters using the exact same encryption scheme Authlogic uses to encrypt passwords when it verifies passwords during authentication. I need to 1) encrypt the password the user enters and 2) do a string comparison between this encryption and the encrypted password stored in the database for the user.
Where should I put the method to perform this encryption? Here are some ideas:
Idea 1 (in a new, custom module)
module PasswordCryption
include Authlogic::ActsAsAuthentic::Password
encrypt_password(password)
end
end
Idea 2 (in the User model)
class User
acts_as_authentic <---- makes Authlogic password encryption functionality available
encrypt_password(password)
end
end
Authlogic uses the SHA512 encryption by default. The clue is that authlogic repeated the hexdigest function 20 times. This will solve your problem:
digest = [raw_password, password_salt].join('')
crypted_password = 20.times { digest = Digest::SHA512.hexdigest(digest) }