views:

2193

answers:

4

I need to authenticate users from database, Spring Security documents don't tell how to authenticate with hibernate. Is that possible and how can I do that?

+5  A: 

You have to make you're own custom authentication-provider.

Example code:

Service to load Users from Hibernate:

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;    

@Service("userDetailsService") 
public class UserDetailsServiceImpl implements UserDetailsService {

  @Autowired private UserDao dao;
  @Autowired private Assembler assembler;

  @Transactional(readOnly = true)
  public UserDetails loadUserByUsername(String username)
      throws UsernameNotFoundException, DataAccessException {

    UserDetails userDetails = null;
    UserEntity userEntity = dao.findByName(username);
    if (user == null)
      throw new UsernameNotFoundException("user not found");

    return = assembler.buildUserFromUserEntity(userEntity);
  }
}

Service to conver you're entity to a spring user object:

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;

@Service("assembler")
public class Assembler {

  @Transactional(readOnly = true)
  User buildUserFromUserEntity(UserEntity userEntity) {

    String username = userEntity.getName();
    String password = userEntity.getPassword();
    boolean enabled = userEntity.isActive();
    boolean accountNonExpired = userEntity.isActive();
    boolean credentialsNonExpired = userEntity.isActive();
    boolean accountNonLocked = userEntity.isActive();

    Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    for (SecurityRoleEntity role : userEntity.getRoles()) {
      authorities.add(new GrantedAuthorityImpl(role.getRoleName()));
    }

    User user = new User(username, password, enabled,
      accountNonExpired, credentialsNonExpired, accountNonLocked, authorities, id);
    return user;
  }
}

The namespace-based application-context-security.xml would look something like:

<http>
  <intercept-url pattern="/login.do*" filters="none"/>
  <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
  <form-login login-page="/login.do"
              authentication-failure-url="/login.do?error=failed"
              login-processing-url="/login-please.do" />
  <logout logout-url="/logoff-please.do"
          logout-success-url="/logoff.html" />
</http>

<beans:bean id="daoAuthenticationProvider"
 class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <beans:property name="userDetailsService" ref="userDetailsService"/>
</beans:bean>

<beans:bean id="authenticationManager"
    class="org.springframework.security.authentication.ProviderManager">
  <beans:property name="providers">
    <beans:list>
      <beans:ref local="daoAuthenticationProvider" />
    </beans:list>
  </beans:property>
</beans:bean>

<authentication-manager>
  <authentication-provider user-service-ref="userDetailsService">
    <password-encoder hash="md5"/>
  </authentication-provider>
</authentication-manager>
Kdeveloper
Thanks for good and detailed answer with full code. Can you tell my why Assembler class is needed, why can't you just put that code in the loadUserByUsername method ??
newbie
You’re right, there is no real need for the Assembler. Just thought it was a good idea to keep the userDetailsService simple and make the conversion reusable via the assembler service.
Kdeveloper
A: 

Hi guys im currently using Spring Security 2.x. Can i just check, are UserEntity and SecurityRoleEntity valid types? because it seems that they are not valid on my implementation. please advice!

sean
A: 

When using the code above,I got error: Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userDetailsService' is defined at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:510) at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1056) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:274) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322) ... 56 more

Tom
A: 

Thanks for that. I have used with jdbctemplate.

Vinicius