shiro校验框架

shiro

AuthorizingRealm

配置用户角色权限

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
/**
* 自定义用户认证授权
*
* @Author: Administrator
**/
@Slf4j
public class UserRealm extends AuthorizingRealm {
/**
* 系统角色业务接口
*/
@Autowired
private ISysRoleService roleService;
/**
* 系统菜单业务接口
*/
@Autowired
private SysMenuService menuService;
/**
* 登陆业务接口
*/
@Autowired
private LoginService loginService;


/**
* 用户授权
* 通过用户ID查询 角色表、权限表、角色权限映射表
*
* @param principals 主要信息
* @return 授权信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SysUser user = ShiroUtils.getSysUser();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
boolean isRoot = ShiroUtils.isRoot();
if (isRoot) {
info.addRole(ShiroUtils.ROOT);
info.addStringPermission("*:*:*");
} else {
//通过当前账号ID查询对应角色 //角色列表
Set<String> roles = roleService.listRoleKeys(user.getUserId());
//通过当前账号ID查询对应权限 //功能列表
Set<String> menus = menuService.listMenusCodeByUserId(user.getUserId());

info.setRoles(roles);
info.setStringPermissions(menus);
}
return info;
}

/**
* 清除缓存认证信息
*/
public void clearCachedAuthorizationInfo() {
this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
}
}

用户认证

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
/**
* 用户认证
*
* @param token 认证Token
* @return 认证信息
* @throws AuthenticationException 认证异常
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
if (token instanceof JwtToken){
JwtToken jwtToken = (JwtToken) token;
SysUser user=loginService.loginByJwtToken(jwtToken);
//这里密码为空不能写成null,否则改版本会有空指针异常 addby xucy 2023-11-28 10:12:40
return new SimpleAuthenticationInfo(user,new char[]{}, getName());
}
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
String password = "";
if (upToken.getPassword() != null) {
password = new String(upToken.getPassword());
}
SysUser user = null;
try {
String host = upToken.getHost();
if(StringUtils.isBlank(host)|| Objects.equals(EnumHost.PC.getCode(),host)){
user = loginService.login(username, password);
}
if(Objects.equals(EnumHost.MOBILE.getCode(),host)){
String phone=username;
user = loginService.loginByPhone(phone);
}

} catch (UserNotExistsException e) {
//用户不存在
throw new UnknownAccountException(e.getMessage(), e);
} catch (UserBlockException e) {
//账户被锁定
throw new LockedAccountException(e.getMessage(), e);
} catch (UserPasswordNotMatchException e) {
//用户名或密码错误
throw new IncorrectCredentialsException(e.getMessage(), e);
} catch (UserPasswordRetryLimitExceedException e) {
//密码错误最大次数异常
throw new ExcessiveAttemptsException(e.getMessage(), e);
} catch (UserDeleteException e) {
//用户被删除
throw new DisabledAccountException(e.getMessage(), e);
}
// user 是数据库查询到的用户信息, password 是用户填的密码
return new SimpleAuthenticationInfo(user, password, getName());
}

会话保存

配置Session,以redis为介质,登录返回给浏览器cookie,浏览器请求携带cookie校验登录状态

登录逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@PostMapping("/login")
@ResponseBody
public AjaxResult ajaxLogin(String username, String password, String host) {
if (StringUtils.isBlank(password)) {
password = username;//密码要有值,否则会报credentials错误
}
// 登录核心!
UsernamePasswordToken token = new UsernamePasswordToken(username, password, host);
Subject subject = SecurityUtils.getSubject();
try {
subject.login(token);
} catch (AuthenticationException e) {
String msg = "用户名或密码错误";
if (e.getMessage() != null) {
msg = e.getMessage();
}
return new AjaxResult(AjaxResult.Type.WARN, msg);
}
//判断是否为正版用户
if (!licLicenseService.verifyLicense()) {
return new AjaxResult(AjaxResult.Type.WARN, "非授权用户,请联系开发商");
}
return new AjaxResult(AjaxResult.Type.SUCCESS, "登陆成功");
}