使用Hibernate进行Spring Security 3数据库身份验证

new*_*bie 69 database authentication hibernate spring-security

我需要从数据库验证用户,Spring Security文档不告诉如何使用hibernate进行身份验证.这可能吗?我该怎么做?

Kde*_*per 134

您必须创建自己的自定义身份验证提供程序.

示例代码:

从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 (userEntity == null)
      throw new UsernameNotFoundException("user not found");

    return assembler.buildUserFromUserEntity(userEntity);
  }
}
Run Code Online (Sandbox Code Playgroud)

将您的实体转换为spring用户对象的服务:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

基于命名空间的application-context-security.xml看起来像:

<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>
Run Code Online (Sandbox Code Playgroud)

  • 不推荐使用`GrantedAuthorityImpl`,而是使用`SimpleGrantedAuthority` (7认同)
  • 感谢您提供完整代码的详细解答.你能告诉我为什么需要Assembler类,你为什么不能把这些代码放在loadUserByUsername方法中? (3认同)
  • 自动装配如何为userDetailsS​​ervice工作,我的自动装配不起作用.我必须在security xml中定义userDetailsS​​ervice bean.任何的想法.自动装配正在工作的其他地方 (2认同)
  • @Nikola你不检查自己密码(哈希)是否匹配,Spring Security会自动为你做这件事.如果密码错误,则Spring Security会重定向到Spring Security XML配置中定义的错误密码URL.您只需提供User对象,其中密码通过正确的散列算法进行散列.如果需要,您也可以使用密码盐,但这需要更多配置. (2认同)