Question

I'm building a web application using Stripes and Spring. It needs to have a login/authentication feature. Right now I store user information separate from user credentials in the database. My User model does not contain the credentials as I don't want to be passing around valuable passwords.

Spring manages all of my DAO's.

Now, I am implementing a non-container based security system. I store the sha-2 hash of the password and perform a comparison on the password that was submitted in the form against what is stored in the database. This comparison has been tested and works. I'm trying to figure out how to wire this thing together. Right now I have a LoginActionBean that catches the login requests and uses a "PasswordService" singleton that uses a UserDAO internally to retrieve credentials and perform comparison against the parameters submitted. My spring bean is:

<bean id="passwordSerivce" class="com.example.store.authentication.PasswordService" factory-method="getInstance">
    <property name="userDAO" ref="userDAO"/>
</bean>

But it then the PasswordService singleton needs a:

public void setUserDAO(UserDAO userDAO) { ...}

method which doesn't really make sense in a singleton (UserDAO is an interface).

I'm looking for a proper design. I've read that ServiceLocators are the very reason Spring was invented. Any thoughts?

I'd also like to know how else I can design this. I have an ActionBean that is called when the user clicks "Login", but how do I actually authenticate. Do I inject the authentication service into the bean? Do i create a singleton that anyone can call? Do I have a generic interface that the LoginAcionBean uses which Spring injects? If I wasn't using Spring, how would it be done?

Was it helpful?

Solution

  1. I don't understand why it doesn't make any sense to inject the userDao.

  2. I don't understand why your xml is using factory-method="getInstance"; you can throw away all the instance stuff and singleton stuff; spring will instantiate a single instance of the password service class and inject it into however many classes need it, and they'll all get the same instance. So spring is creating a singleton for you. The password service class can be a simple pojo. Similarly for the userDao implementation.

I'd also advise looking at, understanding, and using the spring annotations. Basically you use @Service on the class that will be injected, then use @Autowired on the setter in the class where it's injected. You also need to add something to your xml configuration file to turn on the annotation stuff.

OTHER TIPS

Adding to the above answer, just use constructor injection if you don't want a setter for the DAO:

<bean id="passwordSerivce" class="...PasswordService">
   <constructor-arg ref="userDAO"/>
</bean>

Unless the bean is not a class you control, you don't need to make it a Singleton, Spring will do that by default.

I personally am not a fan of annotations.

My solution was to have an interface with an "authenticate" method. Then create a service class that implements the interface with a constructor that takes in a UserDAO object. This way, the object that requires the service doesn't perform instantiation (it's done by spring) and is unaware of what underlying implementation is performed (ldap, SSO, simple password comparison, etc). Seems to get the job done :P

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top