第一步 新建UserRealm 1.做登陆认证(执行一次) 把登陆后该用户的权限信息,存到session中 2.做权限控制授权 把session中的信息拿出来 User user = (User) principals.getPrimaryPrincipal(); 然后授权(执行多次) simpleAuthorizationInfo.addRoles(roles); simpleAuthorizationInfo.addStringPermissions(permissions); -----------弊端--------懒加载权限配置后需要重新登陆,且登陆时间长 第二种方法 1.UserRealm 做登陆认证 只做登陆认证,不查询权限信息,权限信息不放入session 2.(有session的id,就可以查询所以登陆了)加载菜单,同时把权限(菜单地址)信息放入redis中 3.UserRealm 做授权,把redis的权限信息取出来授权(执行多次) 4.修改权限时,redis被改,因为授权执行多次,使用权限注解,都会执行,所以无需重新登陆 第一种 @Configuration public class UserRealm extends AuthorizingRealm{ /** * 授权 执行n次 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { User user = (User) principals.getPrimaryPrincipal(); List<String> roles = user.getRoles();//取出权限信息 List<String> permissions = user.getPermissions(); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); simpleAuthorizationInfo.addRoles(roles); simpleAuthorizationInfo.addStringPermissions(permissions); return simpleAuthorizationInfo; } /** * 登录 执行一次 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = token.getPrincipal().toString(); // 使用用户名查询用户 // 查询该用户的权限信息 // 返回AuthenticationInfo 对象 User user = new User(); user.setUsername(username); user.setPassword("b53b8594f4e0ec33b5f3ed8c29c2a81b"); user.setRoles(Arrays.asList("admin"));//模拟权限信息 user.setPermissions(Arrays.asList("admin:add"));//模拟权限信息 ByteSource salt = ByteSource.Util.bytes("whsxt".getBytes()); return new SimpleAuthenticationInfo(user, user.getPassword(), salt,username);//存 } } 第二种------------------------------------------------------- @Configuration public class UserRealm extends AuthorizingRealm{ @Autowired private SysUserService userService; @Autowired private StringRedisTemplate redis; /** * * 授权 执行n次 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SysUser user = (SysUser)principals.getPrimaryPrincipal(); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); String authJson = redis.opsForValue().get(Auth.USER_AUTH_PREFIX+user.getUserId());//redis中取权限信息 JSONArray jsonArray =JSONUtil.parseArray(authJson); // 只要简单的权限 List<String> permissions = JSONUtil.toList(jsonArray, String.class); simpleAuthorizationInfo.addStringPermissions(permissions); return simpleAuthorizationInfo; } /** * 登录 执行一次 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = token.getPrincipal().toString(); // 使用用户名查询用户 SysUser sysUser = userService.findUserByUsername(username); if(sysUser==null) { // 若用户不存在,应该return null ,而不是把null 也放在SimpleAuthenticationInfo 里面 return null ; } // 查询该用户的权限信息 ,但是若是权限或菜单查询失败,则用户就登录失败 了 // 返回AuthenticationInfo 对象 return new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), ByteSource.Util.bytes("whsxt".getBytes()),username); } }