16
votes

I am new to Spring.

We are using spring security feature. Database connectivity: eclipselink implementation of JPA. Database: MySql

While using spring security, Configuration of authentication provider is as follows,-

<authentication-provider>

    <jdbc-user-service id="userDetailsService" data-source-ref="Datasource" />

    </authentication-provider>

But in JPA we do not define datasource, we use Persistence unit with provider jpa.PersistenceProvider.

So how do we configure authentication provider so as to use JPA for database connectivity?

What exactly should data-source-ref field contain to use database for authentication?

Thank you in advance.

2

2 Answers

22
votes

Basically you probably need to implement UserDetailsService yourself.

So you would for example have a User entity, and your UserDetailsService implementation would look up the user and convert it to a UserDetails object (or your entity would have to implement UserDetails).

Sample implementation:

public class MyUserDetailsService implements UserDetailsService{

    private EntityManager entityManager;
    @PersistenceContext
    public void setEntityManager(EntityManager newEm){
        this.entityManager = newEm;
    }

    public UserDetails loadUserByUsername(String username){

        // assuming that you have a User class that implements UserDetails
        return entityManager.createQuery("from User where username = :username", User.class)
                            .setParameter("username", username)
                            .getSingleResult();

    }
}

And you add this to user spring-security.xml

<authentication-manager>
   <authentication-provider user-service-ref="MyUserDetailsService" />
</authentication-manager>
12
votes

An easier way for authentication in your case is to get one of your service layer classes implement org.springframework.security.core.userdetails.UserDetailsService interface. This interface contain only one method UserDetails loadUserByUsername(String username). You have to make sure that you return a UserDetails instance for a given username.

public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException, DataAccessException {
    // load and return user using your regular JPA techniques here
        ...
    }

Once you have implemented this method in your service class, you will simply need to add its reference your spring configuration file:

<authentication-manager>
     <authentication-provider user-service-ref="myServiceLayerClassInstance">
     </authentication-provider>
</authentication-manager>