Search code examples
javadatabasedaoshirojdbcrealm

How to store hashed pws into a db with Apache Shiro?


I have been looking all over the place with no luck to what I am trying to do.

I am looking to hash and salt my user passwords and store them into the DB. The issue is, how do I store them?

I have looked at this http://shiro.apache.org/realm.html#Realm-authentication which I have found similar answers, but it doesn't make sense.

import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
...

//We'll use a Random Number Generator to generate salts.  This
//is much more secure than using a username as a salt or not
//having a salt at all.  Shiro makes this easy.
//
//Note that a normal app would reference an attribute rather
//than create a new RNG every time:
RandomNumberGenerator rng = new SecureRandomNumberGenerator();
Object salt = rng.nextBytes();

//Now hash the plain-text password with the random salt and multiple
//iterations and then Base64-encode the value (requires less space than Hex):
String hashedPasswordBase64 = new Sha256Hash(plainTextPassword, salt, 1024).toBase64();

User user = new User(username, hashedPasswordBase64);
//save the salt with the new account.  The HashedCredentialsMatcher
//will need it later when handling login attempts:
user.setPasswordSalt(salt);
userDAO.create(user);

User nor "UserDAO" exists currently from what I'm seeing, and all of these examples seem to use older Shiro examples.

When I look at the "PasswordService" javadoc I read

Account Creation or Password Reset

Whenever you create a new user account or reset that account's password,

we must translate the end-user submitted raw/plaintext password value to a string format that is much safer to store. You do that by calling the encryptPassword(Object) method to create the safer value. For example:

 String submittedPlaintextPassword = ...
 String encryptedValue = passwordService.encryptPassword(submittedPlaintextPassword);
 ...
 userAccount.setPassword(encryptedValue);
 userAccount.save(); //create or update to your data store

Be sure to save this encrypted password in your data store 
and never the original/raw submitted password.

but what is "userAccount?"

A lot of times the documentation is very vague.

However I did notice there is a "SubjectDAO" Class, but no UserDAO class...

So yeah I'm confused on what to do next, so if anyone could help me I would appreciate it greatly!

Thanks a lot!


Solution

  • Seems like the Documentation is refering User and UserDAO as your own User Model Entity (Table) and User Data Access Layer Entity (Class to Save, Update, Delete and Retrieve). These necessarily not required to be a part of Apache Shiro (Reason some Data Access Layer may be in RDBMS, Some in In-memory dbs, some could even be in properties file, why not?)

    You must implement User and UserDAO to save to your own persistence store.

    UserAccount also is the Model object you use when you want to register user accounts. Like the Gmail signup.

    You must know that Apache Shiro is just a layer for Security (Authentication, Authorization, etc). Persistence must be implemented by you.

    Strongly advice you to check out Spring Data JPA and Spring Security.