上篇实例中的用户都是使用的默认用户,在实际项目中用户都是通过自建表实现的,在这一篇中我们通过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();
}
}
输入用户名密码点击登陆,登陆成功
