ShiroFilterMapFactory.java
package com.szcl.verify.shiro.config; import java.util.LinkedHashMap; import java.util.Map; /** * @ClassName: ShiroFilterMapFactory * @author YoungJ * @date 2020年8月26日 * */ public class ShiroFilterMapFactory { public static Map<String, String> shiroFilterMap() { // 设置路径映射,注意这里要用LinkedHashMap 保证有序 LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); //对所有用户认证 filterChainDefinitionMap.put("/static/**", "anon"); filterChainDefinitionMap.put("/admin/login", "anon"); filterChainDefinitionMap.put("/admin/logout", "logout"); //放验证码 filterChainDefinitionMap.put("/captcha/**", "anon"); // 释放 druid 监控画面 filterChainDefinitionMap.put("/druid/**", "anon"); //释放websocket请求 filterChainDefinitionMap.put("/websocket", "anon"); //前端 filterChainDefinitionMap.put("/", "anon"); filterChainDefinitionMap.put("/index", "anon"); filterChainDefinitionMap.put("/quartz/**", "anon"); //开放APicontroller filterChainDefinitionMap.put("/ApiController/**", "anon"); //对所有页面进行认证 filterChainDefinitionMap.put("/**","authc"); return filterChainDefinitionMap; } }MyShiroRealm.java
/** * 身份校验核心类 * * @author YoungJ * @date 2020年8月25日 */ @Service public class MyShiroRealm extends AuthorizingRealm { @Autowired private UserMapper tsysUserDao; @Autowired private PermissionMapper permissionDao; @Autowired private RoleMapper roleDao; /** * 认证登陆 */ @SuppressWarnings("unused") @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { if (token.getPrincipal() == null) { return null; } String username = (String) token.getPrincipal(); String password = new String((char[]) token.getCredentials()); // 通过username从数据库中查找 User对象 // 实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法 User userInfo = tsysUserDao.queryUserName(username); if (userInfo == null) { return null; } else { //错误次数控制 checkLoginErrorTimes(username); //单一登录控制 checkSingleSingOn(userInfo); return new SimpleAuthenticationInfo( userInfo, userInfo.getPassword(), getName() ); } } /** * 错误次数控制 * @param userName */ private void checkLoginErrorTimes(String userName) { } /** * 单一登录控制 * @param user */ private void checkSingleSingOn(User user) { DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager(); DefaultWebSessionManager sessionManager = (DefaultWebSessionManager) securityManager.getSessionManager(); //获取当前已登录的用户session列表 SessionDAO sessionDAO = sessionManager.getSessionDAO(); Collection<Session> sessions = sessionDAO.getActiveSessions(); for (Session session : sessions) { //清除该用户以前登录时保存的session Object obj = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); SimplePrincipalCollection coll = (SimplePrincipalCollection) obj; if(coll !=null){ User userLogin = (User)coll.getPrimaryPrincipal(); if(user.getUsername().equals(userLogin.getUsername())){ sessionDAO.delete(session); } } } } /** * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用. */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { if (principals == null) { throw new AuthorizationException("principals should not be null"); } SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); User userinfo = (User) principals.getPrimaryPrincipal(); Long id = userinfo.getId(); List<Role> tsysRoles = roleDao.queryUserRole(id); for (Role userrole : tsysRoles) { Long rolid = userrole.getId(); authorizationInfo.addRole(userrole.getName()); List<Permission> permissions = permissionDao.queryRoleId(rolid); for (Permission p : permissions) { if (StringUtils.isNotEmpty(p.getPerms())) { authorizationInfo.addStringPermission(p.getPerms()); } } } return authorizationInfo; } /** * 清理缓存权限 */ public void clearCachedAuthorizationInfo() { this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals()); } }ShiroUtils.java
/** * shiro 工具类 * * @author YoungJ */ public class ShiroUtils { private ShiroUtils() { } /** * 获取shiro subject * * @return * @author YoungJ * @Date 2019年11月21日 上午10:00:55 */ public static Subject getSubjct() { return SecurityUtils.getSubject(); } /** * 获取登录session * * @return * @author YoungJ * @Date 2019年11月21日 上午10:00:41 */ public static Session getSession() { return SecurityUtils.getSubject().getSession(); } /** * 退出登录 * * @author YoungJ * @Date 2019年11月21日 上午10:00:24 */ public static void logout() { getSubjct().logout(); } /** * 获取登录用户model * * @return * @author YoungJ * @Date 2019年11月21日 上午10:00:10 */ public static User getUser() { User user = null; Object obj = getSubjct().getPrincipal(); if (!StringUtils.isEmpty(obj)) { user = new User(); BeanUtils.copyBeanProp(user, obj); } return user; } /** * set用户 * * @param user * @author YoungJ * @Date 2019年11月21日 上午9:59:52 */ public static void setUser(User user) { Subject subject = getSubjct(); PrincipalCollection principalCollection = subject.getPrincipals(); String realmName = principalCollection.getRealmNames().iterator().next(); PrincipalCollection newPrincipalCollection = new SimplePrincipalCollection(user, realmName); // 重新加载Principal subject.runAs(newPrincipalCollection); } /** * 清除授权信息 * * @author YoungJ * @Date 2019年11月21日 上午9:59:37 */ public static void clearCachedAuthorizationInfo() { RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager(); MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next(); realm.clearCachedAuthorizationInfo(); } /** * 获取登录用户id * * @return * @author YoungJ * @Date 2019年11月21日 上午9:58:55 */ public static Long getUserId() { User tsysUser = getUser(); if (tsysUser == null || tsysUser.getId() == null) { throw new RuntimeException("用户不存在!"); } return tsysUser.getId(); } /** * 获取登录用户name * * @return * @author YoungJ * @Date 2019年11月21日 上午9:58:48 */ public static String getLoginName() { User tsysUser = getUser(); if (tsysUser == null) { throw new RuntimeException("用户不存在!"); } return tsysUser.getUsername(); } /** * 获取登录用户ip * * @return * @author YoungJ * @Date 2019年11月21日 上午9:58:26 */ public static String getIp() { return getSubjct().getSession().getHost(); } /** * 获取登录用户sessionid * * @return * @author YoungJ * @Date 2019年11月21日 上午9:58:37 */ public static String getSessionId() { return String.valueOf(getSubjct().getSession().getId()); } /** * 缓存获取当前用户权限 */ public static Set<String> getPermissions() { Set<String> userPermissions = (Set<String>) SecurityUtils.getSubject().getSession().getAttribute(Constants.SHIRO_PERMISSIONKEY); return userPermissions; } /** * 设置权限缓存 */ public static void setPermissions(Set<String> userPermissions) { Session session = SecurityUtils.getSubject().getSession(); session.setAttribute(Constants.SHIRO_PERMISSIONKEY, userPermissions); } /** * 设置缓存 */ public static void setCacheParam(String key, Object value) { Session session = SecurityUtils.getSubject().getSession(); session.setAttribute(key, value); } /** * 获取缓存 */ public static Object getCacheParam(String key) { Session session = SecurityUtils.getSubject().getSession(); return session.getAttribute(key); } }LoginController.java
@Controller public class LoginController { private static Logger log = LoggerFactory.getLogger(LoginController.class); @Autowired private IPermissionService permissionService; @GetMapping("/index") public String index(HttpServletRequest request) { Long userId = null; try { userId = ShiroUtils.getUserId(); } catch (Exception e) { return "login"; } if (userId == null) { return "login"; } //获取菜单栏 MenuTree tree= permissionService.getTreePerm(userId); // log.info(GsonConvertUtil.toJson(tree)); request.getSession().setAttribute("tree", tree); request.getSession().setAttribute("sessionUserName", ShiroUtils.getUser().getNickname()); return "home"; } @GetMapping("/user/login") public String login(ModelMap model) { try { if ((null != SecurityUtils.getSubject() && SecurityUtils.getSubject().isAuthenticated()) || SecurityUtils.getSubject().isRemembered()) { return "redirect:index"; } else { return "login"; } } catch (Exception e) { log.error(e.getMessage(), e); } return "login"; } @PostMapping(value = "/user/login") @ResponseBody public BaseDTO<String> login(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam(value = "isRemeberMe", required = false) Boolean isRemeberMe, Model model) { try { if ((null != SecurityUtils.getSubject() && SecurityUtils.getSubject().isAuthenticated()) || SecurityUtils.getSubject().isRemembered()) { return DtoConvertUtil.toDTO(null, "登录成功", Constants.CODE_SUCCESS, true); } else { System.out.println("--进行登录验证..验证开始"); Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordToken token =new UsernamePasswordToken(username, password); if (isRemeberMe != null && isRemeberMe) { token.setRememberMe(true); } currentUser.login(token); // 设置登录过期时间30分钟 SecurityUtils.getSubject().getSession().setTimeout(30 * 60 * 1000); // model.addAttribute("RollVerification", V2Config.getRollVerification()); // System.out.println("V2Config.getRollVerification()>>>"+V2Config.getRollVerification()); return DtoConvertUtil.toDTO(null, "登录成功", Constants.CODE_SUCCESS, true); } }catch (UnknownAccountException e) { log.error("[登录异常] >> 账户不存在 account : {}", username); model.addAttribute("msg", "账号不存在"); return DtoConvertUtil.toDTO(null, "账号不存在", Constants.CODE_PARAMA_ERR, false); } catch (IncorrectCredentialsException e) { log.error("[登录异常] >> 密码错误 account : {}", username); model.addAttribute("msg", "密码错误"); return DtoConvertUtil.toDTO(null, "密码错误", Constants.CODE_PARAMA_ERR, false); } catch (LockedAccountException e) { log.error("[登录异常] >> 账户已锁定 account : {}", username); model.addAttribute("msg", "账户已锁定"); return DtoConvertUtil.toDTO(null, "账户已锁定", Constants.CODE_PARAMA_ERR, false); } catch (DisabledAccountException e) { log.error("[登录异常] >> 账户已停用 account : {}", username); model.addAttribute("msg", "账户已停用"); return DtoConvertUtil.toDTO(null, "账户已停用", Constants.CODE_PARAMA_ERR, false); } catch (Exception e) { log.error("[登录异常] >> 未知异常 account : {}", username); model.addAttribute("msg", "未知异常"); return DtoConvertUtil.toDTO(null, "未知异常", Constants.CODE_PARAMA_ERR, false); } } @GetMapping("/loginout") public String loginOut(HttpServletRequest request, HttpServletResponse response){ //在这里执行退出系统前需要清空的数据 ShiroUtils.logout(); return "redirect:/user/login"; } }controller请求权限判断
/** * 修改保存用户 */ //@Log(title = "修改保存用户", action = "1") @ApiOperation(value = "修改保存用户", notes = "修改保存用户") @RequiresPermissions("system:user:edit") @PostMapping("/user/edit") @ResponseBody public BaseDTO<String> editSave(User user, @RequestParam(value = "roles") List<Long> roles) { if (roles == null || roles.isEmpty()) { return DtoConvertUtil.toDTO(null, "请选择角色", Constants.CODE_NO_PERMISSION, false); } userService.updateUserRoles(user, roles); return DtoConvertUtil.toDTO(null, "保存成功", Constants.CODE_SUCCESS, true); }页面权限判断
<html class="x-admin-sm" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <shiro:hasPermission name="system:user:edit"> </shiro:hasPermission>