package cc.mrbird.febs.common.authentication; import cc.mrbird.febs.system.entity.Menu; import cc.mrbird.febs.system.entity.Role; import cc.mrbird.febs.system.entity.User; import cc.mrbird.febs.system.service.IMenuService; import cc.mrbird.febs.system.service.IRoleService; import cc.mrbird.febs.system.service.IUserDataPermissionService; import cc.mrbird.febs.system.service.IUserService; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * 自定义实现 ShiroRealm,包含认证和授权两大模块 * * @author MrBird */ @Component public class ShiroRealm extends AuthorizingRealm { private IUserService userService; private IRoleService roleService; private IMenuService menuService; private IUserDataPermissionService userDataPermissionService; @Autowired public void setMenuService(IMenuService menuService) { this.menuService = menuService; } @Autowired public void setUserService(IUserService userService) { this.userService = userService; } @Autowired public void setRoleService(IRoleService roleService) { this.roleService = roleService; } @Autowired public void setUserDataPermissionService(IUserDataPermissionService userDataPermissionService) { this.userDataPermissionService = userDataPermissionService; } /** * 授权模块,获取用户角色和权限 * * @param principal principal * @return AuthorizationInfo 权限信息 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { User user = (User) SecurityUtils.getSubject().getPrincipal(); String userName = user.getUsername(); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); // 获取用户角色集 List roleList = this.roleService.findUserRole(userName); Set roleSet = roleList.stream().map(Role::getRoleName).collect(Collectors.toSet()); simpleAuthorizationInfo.setRoles(roleSet); // 获取用户权限集 List permissionList = this.menuService.findUserPermissions(userName); Set permissionSet = permissionList.stream().map(Menu::getPerms).collect(Collectors.toSet()); simpleAuthorizationInfo.setStringPermissions(permissionSet); return simpleAuthorizationInfo; } /** * 用户认证 * * @param token AuthenticationToken 身份认证 token * @return AuthenticationInfo 身份认证信息 * @throws AuthenticationException 认证相关异常 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 获取用户输入的用户名和密码 String username = (String) token.getPrincipal(); String password = new String((char[]) token.getCredentials()); // 通过用户名到数据库查询用户信息 User user = this.userService.findByName(username); if (user == null || !StringUtils.equals(password, user.getPassword())) { throw new IncorrectCredentialsException("用户名或密码错误!"); } if (User.STATUS_LOCK.equals(user.getStatus())) { throw new LockedAccountException("账号已被锁定,请联系管理员!"); } String deptIds = this.userDataPermissionService.findByUserId(String.valueOf(user.getUserId())); user.setDeptIds(deptIds); return new SimpleAuthenticationInfo(user, password, getName()); } /** * 清除当前用户权限缓存 * 使用方法:在需要清除用户权限的地方注入 ShiroRealm, * 然后调用其 clearCache方法。 */ public void clearCache() { PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals(); super.clearCache(principals); } }