首页 > 代码库 > spring security使用hibernate进行查询数据库验证

spring security使用hibernate进行查询数据库验证

前面查询数据库采用的都是jdbc方式,如果系统使用的是hibernate,该如何进行呢,下面就是实现步骤,关键还是实现自定义的UserDetailsService
项目结构如下:
技术分享
使用hibernate,pom.xml文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.petter</groupId>  <artifactId>security-hibernate-annotation</artifactId>  <packaging>war</packaging>  <version>1.0-SNAPSHOT</version>  <name>security-hibernate-annotation Maven Webapp</name>  <url>http://maven.apache.org</url>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>1.8</java.version>    <spring.version>4.3.5.RELEASE</spring.version>    <spring.security.version>4.2.1.RELEASE</spring.security.version>    <mysql.connector.version>5.1.40</mysql.connector.version>    <dbcp.version>2.1.1</dbcp.version>      <hibernate.version>5.2.9.Final</hibernate.version>  </properties>  <dependencies>    <!-- database pool -->    <dependency>      <groupId>org.apache.commons</groupId>      <artifactId>commons-dbcp2</artifactId>      <version>${dbcp.version}</version>    </dependency>      <!-- Hibernate ORM -->      <dependency>          <groupId>org.hibernate</groupId>          <artifactId>hibernate-core</artifactId>          <version>${hibernate.version}</version>      </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-core</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-web</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-webmvc</artifactId>      <version>${spring.version}</version>    </dependency>      <!-- ORM integration, e.g Hibernate -->      <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-orm</artifactId>          <version>${spring.version}</version>      </dependency>      <!-- Spring + aspects -->      <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-aspects</artifactId>          <version>${spring.version}</version>      </dependency>    <dependency>      <groupId>org.thymeleaf</groupId>      <artifactId>thymeleaf-spring4</artifactId>      <version>3.0.3.RELEASE</version>    </dependency>    <!-- Spring Security -->    <dependency>      <groupId>org.springframework.security</groupId>      <artifactId>spring-security-web</artifactId>      <version>${spring.security.version}</version>    </dependency>    <dependency>      <groupId>org.springframework.security</groupId>      <artifactId>spring-security-config</artifactId>      <version>${spring.security.version}</version>    </dependency>    <!-- 用于thymeleaf中使用security的标签 -->    <dependency>      <groupId>org.thymeleaf.extras</groupId>      <artifactId>thymeleaf-extras-springsecurity4</artifactId>      <version>3.0.2.RELEASE</version>    </dependency>    <!-- mysql -->    <dependency>      <groupId>mysql</groupId>      <artifactId>mysql-connector-java</artifactId>      <version>${mysql.connector.version}</version>    </dependency>  </dependencies>  <build>    <plugins>      <plugin>        <groupId>org.apache.maven.plugins</groupId>        <artifactId>maven-compiler-plugin</artifactId>        <version>3.3</version>        <configuration>          <source>1.8</source>          <target>1.8</target>          <encoding>utf8</encoding>        </configuration>      </plugin>    </plugins>  </build></project>

一、由于使用hibernate,我们使用jpa自己生成数据库表,具体是

1、用于实现基于持久化Token的记住我功能的表persistent_logins,对应的类是PersistentLogin
package com.petter.model;import javax.persistence.*;import java.util.Date;/** * @author hongxf * @since 2017-04-17 14:42 */@Entity@Table(name = "persistent_logins")public class PersistentLogin {    private String series;    private String username;    private String token;    private Date lastUsed;    @Id    @Column(name = "series")    public String getSeries() {        return series;    }    public void setSeries(String series) {        this.series = series;    }    @Column(name = "username", nullable = false)    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    @Column(name = "token", nullable = false)    public String getToken() {        return token;    }    public void setToken(String token) {        this.token = token;    }    @Temporal(TemporalType.TIMESTAMP)    @Column(name = "last_used", nullable = false)    public Date getLastUsed() {        return lastUsed;    }    public void setLastUsed(Date lastUsed) {        this.lastUsed = lastUsed;    }}

2、用户类User对应表users

package com.petter.model;import javax.persistence.*;import java.util.HashSet;import java.util.Set;/** * @author hongxf * @since 2017-04-17 10:29 */@Entity@Table(name = "users")public class User {    private String username;    private String password;    private boolean enabled;    private boolean accountNonExpired;    private boolean accountNonLocked;    private boolean credentialsNonExpired;    private Set<UserRole> userRole = new HashSet<>();    @Id    @Column(name = "username", unique = true, nullable = false, length = 45)    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    @Column(name = "password", nullable = false, length = 60)    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    @Column(name = "enable", nullable = false)    public boolean isEnabled() {        return enabled;    }    public void setEnabled(boolean enabled) {        this.enabled = enabled;    }    @Column(name = "accountNonExpired", nullable = false)    public boolean isAccountNonExpired() {        return accountNonExpired;    }    public void setAccountNonExpired(boolean accountNonExpired) {        this.accountNonExpired = accountNonExpired;    }    @Column(name = "accountNonLocked", nullable = false)    public boolean isAccountNonLocked() {        return accountNonLocked;    }    public void setAccountNonLocked(boolean accountNonLocked) {        this.accountNonLocked = accountNonLocked;    }    @Column(name = "credentialsNonExpired", nullable = false)    public boolean isCredentialsNonExpired() {        return credentialsNonExpired;    }    public void setCredentialsNonExpired(boolean credentialsNonExpired) {        this.credentialsNonExpired = credentialsNonExpired;    }    @OneToMany(fetch = FetchType.EAGER, mappedBy = "user")    public Set<UserRole> getUserRole() {        return userRole;    }    public void setUserRole(Set<UserRole> userRole) {        this.userRole = userRole;    }}

3、用户权限表user_roles对应类UserRole

package com.petter.model;import javax.persistence.*;/** * @author hongxf * @since 2017-04-17 10:32 */@Entity@Table(name = "user_roles", uniqueConstraints = @UniqueConstraint(columnNames = {"role", "username"}))public class UserRole {    private Integer userRoleId;    private User user;    private String role;    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    @Column(name = "user_role_id")    public Integer getUserRoleId() {        return userRoleId;    }    public void setUserRoleId(Integer userRoleId) {        this.userRoleId = userRoleId;    }    @ManyToOne(fetch = FetchType.LAZY)    @JoinColumn(name = "username", nullable = false)    public User getUser() {        return user;    }    public void setUser(User user) {        this.user = user;    }    @Column(name = "role", nullable = false, length = 45)    public String getRole() {        return role;    }    public void setRole(String role) {        this.role = role;    }}

4、用于保存登录失败尝试次数的UserAttempts

package com.petter.model;import javax.persistence.*;import java.util.Date;/** * @author hongxf * @since 2017-03-20 10:50 */@Entity@Table(name = "user_attempts")public class UserAttempts {    private int id;    private String username;    private int attempts;    private Date lastModified;    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    @Column(name = "id")    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    @Column(name = "username")    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    @Column(name = "attempts")    public int getAttempts() {        return attempts;    }    public void setAttempts(int attempts) {        this.attempts = attempts;    }    @Temporal(TemporalType.TIMESTAMP)    @Column(name = "lastModified")    public Date getLastModified() {        return lastModified;    }    public void setLastModified(Date lastModified) {        this.lastModified = lastModified;    }}

二、配置hibernate,在AppConfig类中添加hibernate的配置

package com.petter.config;import org.apache.commons.dbcp2.BasicDataSource;import org.hibernate.SessionFactory;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.orm.hibernate5.HibernateTransactionManager;import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;import org.springframework.transaction.annotation.EnableTransactionManagement;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect;import org.thymeleaf.spring4.SpringTemplateEngine;import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;import org.thymeleaf.spring4.view.ThymeleafViewResolver;import org.thymeleaf.templatemode.TemplateMode;import java.util.Properties;/** * 相当于 * @author hongxf * @since 2017-03-08 10:11 */@EnableWebMvc@Configuration@ComponentScan({"com.petter.*"})@EnableTransactionManagement@Import({SecurityConfig.class})public class AppConfig  {    @Bean    public SessionFactory sessionFactory() {        LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());        builder.scanPackages("com.petter.model")                .addProperties(getHibernateProperties());        return builder.buildSessionFactory();    }    private Properties getHibernateProperties() {        Properties prop = new Properties();        prop.put("hibernate.format_sql", "true");        prop.put("hibernate.show_sql", "true");        prop.put("hibernate.hbm2ddl.auto", "update");        prop.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");        return prop;    }    @Bean(name = "dataSource")    public BasicDataSource dataSource() {        BasicDataSource ds = new BasicDataSource();        ds.setDriverClassName("com.mysql.jdbc.Driver");        ds.setUrl("jdbc:mysql://192.168.11.81:3306/security_learning_3");        ds.setUsername("petter");        ds.setPassword("petter");        return ds;    }    @Bean    public HibernateTransactionManager txManager() {        return new HibernateTransactionManager(sessionFactory());    }    @Bean    public SpringResourceTemplateResolver springResourceTemplateResolver() {        SpringResourceTemplateResolver springResourceTemplateResolver = new SpringResourceTemplateResolver();        springResourceTemplateResolver.setPrefix("/WEB-INF/pages/");        springResourceTemplateResolver.setSuffix(".html");        springResourceTemplateResolver.setTemplateMode(TemplateMode.HTML);        springResourceTemplateResolver.setCacheable(false);        springResourceTemplateResolver.setCharacterEncoding("UTF-8");        return springResourceTemplateResolver;    }    @Bean    public SpringTemplateEngine springTemplateEngine() {        SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();        springTemplateEngine.setTemplateResolver(springResourceTemplateResolver());        springTemplateEngine.addDialect(new SpringSecurityDialect());        return springTemplateEngine;    }    @Bean    public ThymeleafViewResolver thymeleafViewResolver() {        ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();        thymeleafViewResolver.setTemplateEngine(springTemplateEngine());        thymeleafViewResolver.setCharacterEncoding("UTF-8");        return thymeleafViewResolver;    }}

注意这里添加了事务注解@EnableTransactionManagement,否则运行会报无事务错误,并且需要在具体的repository中添加@Transactional注解

三、使用hibernate查询数据库获得User
1、定义接口UserDao
package com.petter.dao;import com.petter.model.User;/** * @author hongxf * @since 2017-04-17 10:41 */public interface UserDao {    User findByUserName(String username);}

2、实现接口UserDao

package com.petter.dao.impl;import com.petter.dao.UserDao;import com.petter.model.User;import org.hibernate.SessionFactory;import org.springframework.stereotype.Repository;import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;import java.util.ArrayList;import java.util.List;/** * @author hongxf * @since 2017-04-17 10:42 */@Repositorypublic class UserDaoImpl implements UserDao {    @Resource    private SessionFactory sessionFactory;    @SuppressWarnings("unchecked")    @Transactional(readOnly = true)    @Override    public User findByUserName(String username) {        List<User> users = sessionFactory.getCurrentSession()                .createQuery("from User where username = ?")                .setParameter(0, username)                .list();        if (users.size() > 0) {            return users.get(0);        } else {            return null;        }    }}

四、实现自定义UserDetailsService

package com.petter.service;import com.petter.dao.UserDao;import com.petter.model.User;import com.petter.model.UserRole;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;/** * security的验证过程会调用指定的UserDetailsService * 自定义的UserDetailsService查询数据库得到自己User后 * 组装org.springframework.security.core.userdetails.User返回 * @author hongxf * @since 2017-04-17 10:45 */@Service("userDetailsService")public class CustomUserDetailsService implements UserDetailsService {    @Resource    private UserDao userDao;    @Override    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        User user = userDao.findByUserName(username);        if (user == null) {            throw new UsernameNotFoundException("该用户不存在:" + username);        }        List<GrantedAuthority> authorities =  buildUserAuthority(user.getUserRole());        return buildUserForAuthentication(user, authorities);    }    // 把自定义的User转换成org.springframework.security.core.userdetails.User    private org.springframework.security.core.userdetails.User buildUserForAuthentication(            User user,            List<GrantedAuthority> authorities) {        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),                user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(), authorities);    }    private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {        Set<GrantedAuthority> setAuths = new HashSet<>();        // Build user‘s authorities        for (UserRole userRole : userRoles) {            setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));        }        return new ArrayList<>(setAuths);    }}

五、修改SecurityConfig配置

package com.petter.config;import com.petter.handler.CustomAuthenticationProvider;import com.petter.service.CustomUserDetailsService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;import javax.annotation.Resource;import javax.sql.DataSource;/** * 相当于spring-security.xml中的配置 * @author hongxf * @since 2017-03-08 9:30 */@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {    @Resource    private DataSource dataSource;    @Resource    private CustomAuthenticationProvider authenticationProvider;    @Resource    private CustomUserDetailsService userDetailsService;    @Bean    public PasswordEncoder passwordEncoder(){        return new BCryptPasswordEncoder();    }    @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {        //authenticationProvider.setPasswordEncoder(passwordEncoder());        //auth.authenticationProvider(authenticationProvider);        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());    }    /**     * 配置权限要求     * 采用注解方式,默认开启csrf     * @param http     * @throws Exception     */    @Override    protected void configure(HttpSecurity http) throws Exception {        http.authorizeRequests()                .antMatchers("/admin/**").hasRole("ADMIN")                .antMatchers("/dba/**").hasAnyRole("ADMIN", "DBA")            .and()                .formLogin().successHandler(savedRequestAwareAuthenticationSuccessHandler())                .loginPage("/login") //指定自定义登录页                .failureUrl("/login?error") //登录失败的跳转路径                .loginProcessingUrl("/auth/login_check") //指定了登录的form表单提交的路径,需与表单的action值保存一致,默认是login                .usernameParameter("user-name").passwordParameter("pwd")            .and()                .logout().logoutSuccessUrl("/login?logout")            .and()                .exceptionHandling().accessDeniedPage("/403")            .and()                .csrf()            .and()                //.rememberMe().rememberMeParameter("remember-me") //其实默认就是remember-me,这里可以指定更换                //.tokenValiditySeconds(1209600)                //.key("hongxf");                .rememberMe().tokenRepository(persistentTokenRepository())                .tokenValiditySeconds(1209600);    }    //如果采用持久化 token 的方法则需要指定保存token的方法    @Bean    public PersistentTokenRepository persistentTokenRepository() {        JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();        db.setDataSource(dataSource);        return db;    }    //使用remember-me必须指定UserDetailsService    @Override    protected UserDetailsService userDetailsService() {        return userDetailsService;    }    /**     * 这里是登录成功以后的处理逻辑     * 设置目标地址参数为targetUrl     * /auth/login_check?targetUrl=/admin/update     * 这个地址就会被解析跳转到/admin/update,否则就是默认页面     *     * 本示例中访问update页面时候会判断用户是手动登录还是remember-me登录的     * 如果是remember-me登录的则会跳转到登录页面进行手动登录再跳转     * @return     */    @Bean    public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler() {        SavedRequestAwareAuthenticationSuccessHandler auth = new SavedRequestAwareAuthenticationSuccessHandler();        auth.setTargetUrlParameter("targetUrl");        return auth;    }}

至此进行测试完全没有问题,但是此处的配置没有实现多次登录失败锁定用户的功能,因为这里没有指定自定义的AuthenticationProvider,使用的是默认的AuthenticationProvider的实现类DaoAuthenticationProvider。

于是使用自定义的AuthenticationProvider实现类CustomAuthenticationProvider
package com.petter.handler;import com.petter.dao.UserDetailsDao;import com.petter.model.UserAttempts;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.security.authentication.BadCredentialsException;import org.springframework.security.authentication.LockedException;import org.springframework.security.authentication.dao.DaoAuthenticationProvider;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.stereotype.Component;import javax.annotation.Resource;import java.util.Date;/** * 自定义验证程序,可以在这里进行其他附属操作,具体验证程序仍然调用上层接口即可 * @author hongxf * @since 2017-03-20 14:28 */@Component("authenticationProvider")public class CustomAuthenticationProvider extends DaoAuthenticationProvider {    @Resource    private UserDetailsDao userDetailsDao;    @Autowired    @Qualifier("userDetailsService")    @Override    public void setUserDetailsService(UserDetailsService userDetailsService) {        super.setUserDetailsService(userDetailsService);    }    @Override    public Authentication authenticate(Authentication authentication) throws AuthenticationException {        try {            //调用上层验证逻辑            Authentication auth = super.authenticate(authentication);            //如果验证通过登录成功则重置尝试次数, 否则抛出异常            userDetailsDao.resetFailAttempts(authentication.getName());            return auth;        } catch (BadCredentialsException e) {            //如果验证不通过,则更新尝试次数,当超过次数以后抛出账号锁定异常            userDetailsDao.updateFailAttempts(authentication.getName());            throw e;        } catch (LockedException e){            //该用户已经被锁定,则进入这个异常            String error;            UserAttempts userAttempts =                    userDetailsDao.getUserAttempts(authentication.getName());            if(userAttempts != null){                Date lastAttempts = userAttempts.getLastModified();                error = "用户已经被锁定,用户名 : "                        + authentication.getName() + "最后尝试登陆时间 : " + lastAttempts;            }else{                error = e.getMessage();            }            throw new LockedException(error);        }    }}

相应的使用hibernate修改之前的UserDetailsDao接口的实现方法

package com.petter.dao.impl;import com.petter.dao.UserDetailsDao;import com.petter.model.UserAttempts;import org.hibernate.SessionFactory;import org.springframework.dao.EmptyResultDataAccessException;import org.springframework.jdbc.core.support.JdbcDaoSupport;import org.springframework.security.authentication.LockedException;import org.springframework.stereotype.Repository;import org.springframework.transaction.annotation.Transactional;import javax.annotation.PostConstruct;import javax.annotation.Resource;import javax.sql.DataSource;import java.util.Date;import java.util.List;/** * @author hongxf * @since 2017-03-20 10:54 */@Repositorypublic class UserDetailsDaoImpl implements UserDetailsDao {    @Resource    private SessionFactory sessionFactory;    private static final int MAX_ATTEMPTS = 3;    @Transactional    @Override    public void updateFailAttempts(String username) {        UserAttempts userAttempts = getUserAttempts(username);        if (userAttempts == null) {            if (isUserExists(username)) { //如果存在这个用户                // 如果之前没有记录,添加一条                userAttempts = new UserAttempts();                userAttempts.setUsername(username);                userAttempts.setAttempts(1);                userAttempts.setLastModified(new Date());                sessionFactory.getCurrentSession().save(userAttempts);            }        } else {            if (isUserExists(username)) {                userAttempts.setAttempts(userAttempts.getAttempts() + 1);                userAttempts.setLastModified(new Date());                sessionFactory.getCurrentSession().update(userAttempts);                sessionFactory.getCurrentSession().flush();            }            if (userAttempts.getAttempts() >= MAX_ATTEMPTS) {                // 大于尝试次数则锁定                sessionFactory.getCurrentSession()                        .createQuery("update User u set u.accountNonLocked =:accountNonLocked where u.username =:username")                        .setParameter("accountNonLocked", false)                        .setParameter("username", username)                        .executeUpdate();                // 并且抛出账号锁定异常                throw new LockedException("用户账号已被锁定,请联系管理员解锁");            }        }    }    @SuppressWarnings("unchecked")    @Transactional(readOnly = true)    @Override    public UserAttempts getUserAttempts(String username) {        List<UserAttempts> list = sessionFactory.getCurrentSession()                .createQuery("from UserAttempts where username =:username")                .setParameter("username", username)                .list();        if (list.size() > 0) {            return list.get(0);        } else {            return null;        }    }    @Transactional    @Override    public void resetFailAttempts(String username) {        sessionFactory.getCurrentSession()                .createQuery("update UserAttempts ua set ua.attempts = 0, ua.lastModified = null where ua.username =:username")                .setParameter("username", username)                .executeUpdate();    }    /**     * 判断用户是否存在     * @param username     * @return     */    private boolean isUserExists(String username) {        boolean result = false;        Long count = (Long) sessionFactory.getCurrentSession()                .createQuery("select count(*) from User u where u.username =:username")                .setParameter("username", username)                .iterate().next();        if (count > 0) {            result = true;        }        return result;    }}

当然最后还要修改下SecurityConfig配置

@Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {        authenticationProvider.setPasswordEncoder(passwordEncoder());        auth.authenticationProvider(authenticationProvider);        //auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());    }

指定自定义的authenticationProvider

其他有关的对应页面和Controlller参考之前的例子即可,运行测试。

spring security使用hibernate进行查询数据库验证