上篇实例中的用户都是使用的默认用户,在实际项目中用户都是通过自建表实现的,在这一篇中我们通过UserDetailService实现spring security查询数据库获取用户。
1.在数据库建用户表ids_member,并插入一条数据
CREATE TABLE `ids_member` ( `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'id', `memberName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户名(登陆)', `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '密码', `realname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '真实姓名', `nickname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '昵称', `gender` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '性别', `age` varchar(3) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '年龄', `tel` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '电话', `officeAddress` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '办公地址', `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '通讯地址', `createdAt` datetime DEFAULT NULL COMMENT '创建时间', `modifiedAt` datetime DEFAULT NULL COMMENT '最后更新时间', `createdBy` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '创建人', `modifiedBy` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '最后修改人', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
2.新建IMemberAuthMapper.java内容如下
@Repository public interface IMemberAuthMapper { /** * 根据用户名查找用户 * * @param memberName * @return */ Member findByMemberName(String memberName); }
3.新建IMemberAuthMapper.xml内容如下
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mfc.springsecuritydemo.dao.mapper.IMemberAuthMapper"> <resultMap id="memberMap" type="com.mfc.springsecuritydemo.domain.Member"> <id property="id" column="id"/> <result property="memberName" column="memberName"/> <result property="username" column="username"/> <result property="realname" column="realname"/> <result property="gender" column="gender"/> <result property="age" column="age"/> <result property="tel" column="tel"/> <result property="officeAddress" column="officeAddress"/> <result property="address" column="address"/> <result property="password" column="password"/> <result property="createdAt" column="createdAt"/> <result property="modifiedAt" column="modifiedAt"/> <result property="createdBy" column="createdBy"/> <result property="modifiedBy" column="modifiedBy"/> </resultMap> <!-- 根据用户名查询用户 --> <select id="findByMemberName" parameterType="String" resultMap="memberMap"> SELECT a.id, a.memberName, username, a.realname, a.gender, a.age, a.tel, a.officeAddress, a.address, a.`password`, a.`createdAt`, a.`modifiedAt`, a.`createdBy`, a.`modifiedBy` FROM ids_member a WHERE a.memberName = #{memberName}; </select> </mapper>
4. 自定义UserDetailService重写loadUserByUsername(String memberName) 方法,改用查询自定义的dao,然后构造User对象
@Service("userDetailService") public class UserDetailService implements UserDetailsService { @Autowired private IMemberAuthMapper memberAuthMapper; @Override public UserDetails loadUserByUsername(String memberName) throws UsernameNotFoundException { Member member = memberAuthMapper.findByMemberName(memberName); if (null == member) { throw new UsernameNotFoundException(memberName); } return new User(member.getMemberName(), member.getPassword(), true, true, true, true, new HashSet<>()); } }
5. 在SecurityConfig 重写configure(AuthenticationManagerBuilder auth)方法,通过AuthenticationManagerBuilder重新设置userDetailsService,为了方便测试使用passwordEncoder设置密码未加密方式(NoOpPasswordEncoder)
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailService userDetailService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login", "/login/authorize") .permitAll() .anyRequest() .authenticated() .and() .formLogin() .loginPage("/login") .loginProcessingUrl("/login/authorize"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailService)// 指定获取用户信息的userDetailsService .passwordEncoder(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } }
输入用户名密码点击登陆,登陆成功