automatically sign in user using springSecurityService - grails

I've tried to sign in user with springSecurityService.reauthenticate(username) but springSecurityService.currentUser is null anyway
How to trigger a sign in with username and password and also get result on springSecurityService.currentUser?

springSecurityService.reauthenticate(username) should set springSecurityService.currentUser at once - at least it does in my application (I'm using spring-security-core:2.0-RC4 and Grails 2.4.4).
Please check if you are passing in an existing username, it looks as though the user cannot be found. Try something along the lines of println User.findByUsername(username) before trying to reauthenticate to debug whether the user can actually be found.
Also check that you are not hitting this problem.

Related

UserManager.AddPassword doesn't work as expected

I am using ASP.NET Identity for membership in MVC5 and have a page for the admin user to manage users and roles. I am trying to allow the admin to change the password for any other user if he needs to do so. I am using this code to perform the task:
userManager.RemovePassword(userId);
userManager.AddPassword(userId, newPassword);
Seems simple enough, but when I try to login with the new password I just created, I can't; I get the invalid password message.
I tried to investigate this issue further by trying to find out how it hashes passwords and discovered this:
string hashed = userManager.PasswordHasher.HashPassword("some password");
Firstly, I am assuming this password hasher is what AddPassword() is using internally.
Secondly, I noticed that each time I run HashPassword('some password'), I get a completely different hash returned to me.
I don't get it...
Alright, I found the problem, it's because of the following line of code in the AccountController:
var user = await UserManager.FindAsync(model.Email, model.Password);
What's happening here is that FindAsync requires a username, not an email and with the user I was testing, the username and email were different.
I wondered if maybe I changed the code in the Login action to pass in the email address and didn't remember... so I created a new MVC5 project and used Nuget to updated to the latest version... well, it looks like that's a bug! Yes, the default implementation actually passes in the email address to FindAsync. Obviously this is because when you register a new user, it sets up the username to be the email address (so they are the same and it doesn't matter). However, they didn't take into account the fact that someone may want to change their username!
Solved!

How does one test AuthController generated by Shiro Grails plugin?

I'm getting very frustrated with the Shiro plugin for Grails. First, I'm trying to set up an ini-based SecurityManager like the beginner tutorial for Shiro suggests, and there's nothing in the documentation that tells me how things get configured. So, after struggling to figure it out, and ultimately failing, I just concede that I have to go with the DbRealm that was generated with the quickstart command. Now I'm trying to discover how things are working by creating a unit test for the generated AuthController. Here's my test code:
void "registered user logs in with valid credentials"() {
given: "user 'root' is registered"
def username = "root"
def password = "secret"
new User(username: username, password: password).save();
when: "user logs in with correct credentials"
params.username = username
params.password = password
controller.signIn();
then: "user should be authenticated"
assertTrue SecurityUtils.subject.authenticated
}
I'm still not sure how to verify the user is actually logged in so I thought the code in the then block should be fine for now. However, every time I try testing the app with grails test-app, I always get:
org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
I'm not exactly new to Grails but it's been a very long time since I last used it, and I never really had that that much exposure to the framework, anyway. However, I know it's supposed to make things less complicated to set up, but the Shiro plugin is giving me a difficult time.
So, how do I go about configuring my app, and/or testing the generated AuthController?

Grails - different passwords for same salt in Spring Security

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

OmniAuth and Devise, how to set optional passwords

I am using OmniAuth and Devise to authenticate users. I would like users that have signed up using OmniAuth providers to be able to set an optional password (needed for API authentication) but I'm running into a wall.
If a user creates an account via OmniAuth and tries to set a password they get the following error:
BCrypt::Errors::InvalidHash in RegistrationsController#update
I believe this is because the password is blank. What's a good way around this? I've thought about generating a random password but the problem with that approach is the user needs to know the current password in order to edit settings.
Edit:
I looked at allowing the user to change settings without requiring a current password and that's what I would like to do only if the user didn't have a password initially.
An alternative is to add the following into your 'user' model class to bypass password verification if there is no password to verify, where provider is some field that is set when using external authentication.
def valid_password?(password)
!provider.nil? || super(password)
end
I assume you don't want the easy way out which would be to simply reset the password if they wanted to set it?
user.send_reset_password_instructions
This comes a bit late but it might help someone else, with Andrew's answer you can in create a password and store it in the database, but you can't login using your email and your new password, solved this by setting:
def valid_password
!provider.nil? && !encrypted_password.present? || super
end
Another alternative. You don't have to include a new field. Just catch the exception raised and return false. Here is the code.
def valid_password?(password)
begin
super(password)
rescue BCrypt::Errors::InvalidHash
return false
end
end
This should do the job.

Authlogic: failed_login_count not updating

I'm using Authlogic as the login system. Everything is working correctly except that it never updates the failed_login_count field when I purposely type in the wrong password. I am using the email as the login item. In the database there is no 'login' column. Is there something that I need to change or add to make this feature work?
Remember: When you login, the Failed_count_field set to 0.
Is your User model valid? If it's not, the validation will fail and the column can't be saved.

Resources