自定义UserDetailsServiceImpl

当什么也没有配置的时候,账号和密码是由Spring Security定义生成的。而在实际项目中账号和密码都是从数据库中查询出来的。 所以我们要通过自定义逻辑控制认证逻辑。

如果需要自定义逻辑时,只需要实现UserDetailsService接口即可。接口定义如下:

UserDetailsServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.atguigu.aclservice.service.impl;

import com.atguigu.aclservice.entity.User;
import com.atguigu.aclservice.service.PermissionService;
import com.atguigu.aclservice.service.UserService;
import com.atguigu.security.entity.SecurityUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.List;

/**
* @author : 其然乐衣Letitbe
* @date : 2022/11/11
*
* 当什么也没有配置的时候,账号和密码是由Spring Security定义生成的。而在实际项目中账号和密码都是从数据库中查询出来的。 所以
* 我们要通过自定义逻辑控制认证逻辑。
* 如果需要自定义逻辑时,只需要实现UserDetailsService接口即可。接口定义如下:
*/
public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired
private UserService userService;

@Autowired
private PermissionService permissionService;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 根据用户名查询数据
User user = userService.selectByUsername(username);

// 判断
if (user == null) {
// 抛出用户名没有发现异常,系统就知道用户名没有查询到
throw new UsernameNotFoundException("用户不存在");
}
com.atguigu.security.entity.User curUser = new com.atguigu.security.entity.User();
BeanUtils.copyProperties(user, curUser);

// 根据用户查询用户权限列表
List<String> permissionValueList = permissionService.selectPermissionValueByUserId(user.getId());
SecurityUser securityUser = new SecurityUser();
UserDetails userDetails = new SecurityUser();
securityUser.setPermissionValueList(permissionValueList);

return securityUser;
}
}

SecurityUser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.atguigu.security.entity;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
* @author : 其然乐衣Letitbe
* @date : 2022/11/10
*/
@Data
@Slf4j
public class SecurityUser implements UserDetails {
//当前登录用户
private transient User currentUserInfo;
//当前权限
private List<String> permissionValueList;
public SecurityUser() {
}
public SecurityUser(User user) {
if (user != null) {
this.currentUserInfo = user;
}
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<>();
for(String permissionValue : permissionValueList) {
if(StringUtils.isEmpty(permissionValue)) {
continue;
}
SimpleGrantedAuthority authority = new
SimpleGrantedAuthority(permissionValue);
authorities.add(authority);
}
return authorities;
}
@Override
public String getPassword() {
return currentUserInfo.getPassword();
}
@Override
public String getUsername() {
return currentUserInfo.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}

User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
* @author : 其然乐衣Letitbe
* @date : 2022/11/10
*/
@Data
@ApiModel(description = "用户实体类")
public class User implements Serializable {

private static final long serialVersionUID = 1L;

/**
* @ApiModelProperty用于swapper测试的
*/
@ApiModelProperty(value = "微信openid")
private String username;

@ApiModelProperty(value = "密码")
private String password;

@ApiModelProperty(value = "昵称")
private String nickName;

@ApiModelProperty(value = "用户头像")
private String salt;

@ApiModelProperty(value = "用户签名")
private String token;

}