) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
该表中包含了用户名、密码、角色、可用状态等信息,然后我们在该表中添加一些测试数据,如下图所示:
![图片](https://img-blog.csdnimg.cn/img_convert/804e7c4ca58b2deddf0dfdd505ac0c98.png)
**2. 创建项目**
准备好了数据库之后,**我们就继续在之前项目的基础之上,创建一个新的model模块,**其基本配置信息和之前一样,具体创建过程略,请参考之前的章节进行项目创建!
**3. 创建User实体类**
/**
* 用户操作实体类
*/
public class User implements UserDetails {
private Long id;
private String username;
private String password;
private String roles;
private boolean enable;
private List authorities;
public String getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return this.enable;
}
public void setAuthorities(List authorities) {
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean equals(Object obj) {
return obj instanceof User?this.username.equals(((User)obj).username):false;
}
@Override
public int hashCode() {
return this.username.hashCode();
}
}
在刚才的模块里,我们先创建一个User实体类,这个用户实体类需要实现 **UserDetails** 接口,并实现接口中的方法。
**核心方法介绍:**
* accountNonExpired、accountNonLocked、credentialsNonExpired、enabled 这四个属性分别用来描述用户的状态,表示账户是否没有过期、账户是否没有被锁定、密码是否没有过期、以及账户是否可用;
* roles 属性表示用户的角色;
* getAuthorities 方法返回用户的角色信息,一个用户可能会有多个角色,所以这里返回值是一个集合类型,我们在这个方法中把自己的 Role 角色稍微转化一下即可。
**4. 定义Mapper接口**
数据模型准备好之后,我们再来定义一个 UserMapper接口,这里我们利用Mybatis进行具体的数据库查询,直接利用注解的方式实现即可。
/**
* @Mapper注解,可带可不带,因为有MapperScan扫描.
*/
@Mapper
public interface UserMapper {
@Select(“SELECT * FROM users WHERE username=#{username}”)
User findByUserName(@Param(“username”) String username);
}
**5. 实现UserDetailsService接口**
接在在service层,定义一个UserDetailsService子类,**实现UserDetailsService接口**,然后实现该接口中的loadUserByUsername()方法。这个方法的参数是用户在登录的时候传入的用户名,然后根据用户名去查询用户信息(查出来之后,系统会自动进行密码比对)。
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 从数据库尝试读取该用户
User user = userMapper.findByUserName(username);
// 用户不存在,抛出异常
if (user == null) {
throw new UsernameNotFoundException(“用户不存在”);
}
// 将数据库形式的roles解析为UserDetails的权限集
// AuthorityUtils.commaSeparatedStringToAuthorityList是Spring Security
//提供的用于将逗号隔开的权限集字符串切割成可用权限对象列表的方法
// 当然也可以自己实现,如用分号来隔开等,参考generateAuthorities
user.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRoles()));
return user;
}
}
主要要在实现方法中,利用user对象的setAuthorities()方法关联用户的所有角色信息,否则用户登录认证时就没有角色,认证也会失败。
**6. 配置SecurityConfig类**
编写完上面的UserDetailsService接口后,接下来我们创建SecurityConfig配置类,我们在configure方法中,关联配置自定义的UserService对象。
@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(“/admin/“)
.hasRole(“ADMIN”)
.antMatchers(”/user/”)
.hasRole(“USER”)
.antMatchers(“/visitor/**”)
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.permitAll();
}
/在数据库中创建用户和角色*************/
@Autowired
private MyUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//关联UserDetailsService对象
auth.userDetailsService(userDetailsService)
//暂时不对密码进行加密配置
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
}
**7. 配置入口类**
我们这里因为是结合Mybatis来实现数据库操作的,所以一定要在入口类中,利用@MapperScan注解进行Mapper组件的扫描。
@SpringBootApplication
@MapperScan(“com.yyg.security.mapper”)
public class Demo03Application {
public static void main(String[] args) {
SpringApplication.run(Demo03Application.class, args);
}
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
最新整理面试题
上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题
最新整理电子书
最新整理大厂面试文档
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
可以帮助到大家。
最新整理面试题
[外链图片转存中…(img-akzbMrj0-1714755325152)]
上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题
最新整理电子书
[外链图片转存中…(img-GDG0PUTd-1714755325153)]
最新整理大厂面试文档
[外链图片转存中…(img-jKm0nnWb-1714755325153)]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。