基于SpringMVC+Ext.js的权限管理系统(无权限框架)
0.准备工作
注意!!!
本案例数据库相关请下载例子包,内有数据库脚本、EXCEL数据表和详细的设计文档(功能流程图,权限说明,数据表设计,接口设计等)。
0.1运行环境
jdk1.6
maven
tomcat7
0.2知识储备
对SpringMVC框架有所了解
对AOP编程有所了解
对权限管理的逻辑有所了解,思维清晰
本案例中等难度,代码注释较少,有不明白的地方,或者不正确的地方,欢迎联系作者本人或留言。
1.设计思路
1.1功能点
- 登录
- 防止重复登录
- token有效期内自动relogin
- 角色管理
- 新增角色、修改角色名与角色权限
- 删除角色(连带删除节点下的所有角色)
- 用户管理
- 按用户名模糊查询,按角色名精确查询
- 新增、修改、删除用户
- 组织结构图
- AOP验权
1.2项目结构

/aspect/ 目录下有两个AOP切面,LoginAspect用于login与relogin。
TokenAspect用于token解析与AOP验权。
/controller/ 目录下HomeController用于返回前端jsp页面与用户登录接口
/controller/auth 目录下Auth.User.Role 三个Control 分别实现权限业务逻辑
/dao/impl 数据库操作相关类
/entity/ Auth.User.Role 三个实体类
/util/ token工具类
1.3项目难点
- 对权限管理的理解
- 前后端分离的数据交互
- 稍有涉及数据结构相关知识
2.具体实现
2.1TokenAspect.java --用于token解析与AOP验权
@Component
@Aspect
public class TokenAspect {
@Autowired
UserImpl userImpl;
@Autowired
AuthImpl authImpl;
private static final Logger LOGGER = LoggerFactory.getLogger(TokenAspect.class);
@Pointcut("execution(* com.yyxl.authDemo.controller.auth.*Controller.*(..))")
public void tokenPointCut() {
// Do nothing.Just @Around By method invoke.
}
@Around("tokenPointCut()")
public Object invoke(ProceedingJoinPoint point) throws Throwable { // NOSONAR
Map<String, Object> result = new HashMap<String, Object>();
HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String tokenInHeader = httpServletRequest.getHeader("Authorization");
Map<String,Object> validRes = JwtUtil.validateToken(tokenInHeader);
if (validRes.containsKey("username")){
String username = (String)validRes.get("username");
//验证username是否存在
TUser tuser = userImpl.getUserByUserame(username);
if (tuser!=null){
//=====AOP验权开始
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String uri = request.getRequestURI();
Boolean aopFlag = false;
//获取接口所需权限
List<TAuth> auths = authImpl.getAuthsByURI(uri);
if (auths.size() != 0) {
for (TAuth a : auths
) {
if (authImpl.isUserhasAuth(username, a.getAuthId())) {
aopFlag = true;
break;
}
}
} else {
//不需要权限
aopFlag = true;
}
if (!aopFlag) {
result.put("success", false);
result.put("msg", "无权限");
return result;
}
//=====AOP验权结束
if (tuser.getToken().equals(tokenInHeader)){
Object[] args = point.getArgs();
if (args.length>0) {
args[args.length - 1] = username;
}
Object returnValue = point.proceed(args);
return returnValue;
}else {
result.put("msg","用户在别处登录");
}
}else {
result.put("msg","用户名不存在");
}
}else {
String msg = (String)validRes.get("msg");
result.put("msg",msg);
}
result.put("success",false);
return result;
}
}
2.2UserController.java
@Controller
@RequestMapping(value = "/user")
public class UserController {
@Autowired
UserImpl userImpl;
@Autowired
RoleImpl roleImpl;
@RequestMapping(value = "/relogin")
@ResponseBody
public Map<String, Object> reLogin(HttpServletRequest httpServletRequest,
@RequestParam(required = false) String username){
Map<String, Object> result = new HashMap<String, Object>();
String tokenInHeader = httpServletRequest.getHeader("Authorization");
Map<String,Object> validRes = JwtUtil.validateToken(tokenInHeader);
if (validRes.containsKey("username")){
String newToken = JwtUtil.generateToken(username);
userImpl.updateTokenByUsername(username, newToken);
result.put("msg","OK");
result.put("token",newToken);
}else {
String msg = (String)validRes.get("msg");
result.put("msg",msg);
}
return result;
}
@RequestMapping(value = "/getAllUsers")
@ResponseBody
public Map<String, Object> getAllUsers(@RequestParam(required = false)Map<String, String> params,
@RequestParam(required = false) String username){
Map<String, Object> result = new HashMap<String, Object>();
int start = Integer.valueOf(params.remove("start"));
int limit = Integer.valueOf(params.remove("limit"));
params.remove("_dc");
params.remove("page");
List<TUser> tusers = userImpl.getUsersByFilter(params,start,limit);
if (tusers.size()!=0) {
for (TUser u : tusers
) {
if (u.getRoleId()!=null) {
String roleName = roleImpl.getRoleNameByRoleId(u.getRoleId()+"");
u.setRoleName(roleName);
}else {
u.setRoleName("无");
}
u.setUpdateTime2(u.getUpdateTime().toString());
u.setCreateTime2(u.getCreateTime().toString());
}
result.put("datas", tusers);
}
result.put("totalSize", tusers.size());
return result;
}
@RequestMapping(value = "/delUser")
@ResponseBody
public Map<String, Object> delUser(@RequestParam Map<String, String> params,
@RequestParam(required = false) String username) {
Map<String, Object> result = new HashMap<String, Object>();
String usernameDel = params.get("username");
userImpl.delUser(usernameDel);
result.put("success", true);
return result;
}
@RequestMapping(value = "/getTreeDatas")
@ResponseBody
public Map<String, Object> getUsersByRole(@RequestParam Integer roleId,
@RequestParam(required = false) String username){
List<TUser> tusers = userImpl.getUsersByRoleId(roleId);
List<Map<String, Object>> treeList = new ArrayList<Map<String,Object>>();
Map<String, Object> result = new HashMap<String, Object>();
for (TUser u:tusers
) {
Map<String, Object> treeMap = new HashMap<String, Object>();
treeMap.put("text", u.getUsername());
treeMap.put("leaf", true);
treeList.add(treeMap);
}
result.put("children",treeList);
return result;
}
@RequestMapping(value = "/saveData")
@ResponseBody
public Map<String, Object> saveData(@RequestParam Map<String, String> params,
@RequestParam(required = false) String username) {
Map<String, Object> result = new HashMap<String, Object>();
String saveState = params.remove("saveState");
result.put("success", true);
result.put("msg", "保存成功");
String usernameNew = params.get("username");
String passwordNew = params.get("password");
String roleName = params.get("roleName");
TRole role = roleImpl.getRoleByRoleName(roleName);
if (role==null){
result.put("success", false);
result.put("msg", "角色名不存在");
return result;
}
TUser userNew = new TUser();
userNew.setUsername(usernameNew);
userNew.setPassword(passwordNew);
userNew.setRoleId(role.getRoleId());
Timestamp now = new Timestamp(System.currentTimeMillis());
userNew.setUpdateTime(now);
if ("add".equals(saveState)) {
userNew.setCreateTime(now);
userImpl.addUser(userNew);
} else {
userImpl.edtUser(userNew);
userImpl.updateTokenByUsername(usernameNew,JwtUtil.generateToken(usernameNew));
}
return result;
}
}
3.展示
3.1token过期

3.2登录

3.3主界面

3.4角色管理

3.5用户管理

不知你们发现了没有,新建用户选择权限第一个是全部,然而全部并不是角色,是筛选条件
3.6组织结构图

3.7AOP验权

4总结
上面是贴出的主要代码,完整的请下载demo包,有不明白的地方请在下方评论,或者联系邮箱yaoyunxiaoli@163.com。
我是妖云小离,这是我第三次在Demo大师上发文章,感谢阅读。基于SpringMVC+Ext.js的权限管理系统(无权限框架)
注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权
基于SpringMVC+Ext.js的权限管理系统(无权限框架)的更多相关文章
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(20)-权限管理系统-根据权限获取菜单
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(20)-权限管理系统-根据权限获取菜单 不知不觉到20讲,真是漫长的日子,可惜最近工作挺忙,要不可以有更多 ...
- 通用权限管理系统之权限菜单zTree树的展示及移动的处理方法
在通用权限管理系统中,有很多数据结构是有父子关系的,如组织机构,部门,权限菜单等,在展示的时候,大多数是通过zTree树的形式展现的,如下: 权限菜单展示 这种数据后台输出比较容易处理,参考如下获取某 ...
- 《Ext JS模板与组件基本知识框架图----模板》
最近在整理Ext JS的模板和组件,在参考<Ext JS权威指南>,<Ext JS Web应用程序开发指南>,<Ext JS API>等相关书籍后才写下这篇< ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(24)-权限管理系统-将权限授权给角色
系列目录 过了个年回来,回顾一下,我们上次讲了角色管理,我们这一次来讲将权限授权给角色,这一节也是大家比较关心的.因为我们已经跑通了整个系统,知道权限的流转,我们先来看一张图 这张图主要分要3块,角色 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(20)-权限管理系统-根据权限获取菜单
系列目录 不知不觉到20讲,真是漫长的日子,可惜最近工作挺忙,要不可以有更多的时间来更新,多谢大家的一路支持.如果你觉得好,记得帮我点击推荐^-^ 我们在之前已经插入一些真实数据,其中包含了一个用户和 ...
- 权限管理系统之项目框架搭建并集成日志、mybatis和分页
前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据. 一.项目框架 首先要解决的是项目框架问题,搭建什么样的 ...
- 零开始:NetCore项目权限管理系统:基础框架搭建
有兴趣的同学可以一起做 喜欢NetCore的朋友,欢迎加群QQ:86594082 源码地址:https://github.com/feiyit/SoaProJect 新建一个空的解决方案,建立对应的解 ...
- spring security 在controller层 方法级别使用注解 @PreAuthorize("hasRole('ROLE_xxx')")设置权限拦截 ,无权限则返回403
1.前言 以前学习的时候使用权限的拦截,一般都是对路径进行拦截 ,要么用拦截器设置拦截信息,要么是在配置文件内设置拦截信息, spring security 支持使用注解的形式 ,写在方法和接口上拦截 ...
- Ext JS 6学习文档–第1章–ExtJS入门指南
Ext JS 入门指南 前言 本来我是打算自己写一个系列的 ExtJS 6 学习笔记的,因为 ExtJS 6 目前的中文学习资料还很少.google 搜索资料时找到了一本国外牛人写的关于 ExtJS ...
随机推荐
- aiohttp/asyncio测试代理是否可用
#!/usr/bin/env python # encoding: utf-8 from proxyPool.db import RedisClient import asyncio import a ...
- 使用EventHandler传递参数
1.MouseEventHandler和EventHandler传递参数的局限性分析 开发过程中,特别是使用自定义控件时,常常需要对一个控件的click,mouseDown,mouseUp等事件的处理 ...
- python 字符串最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow&qu ...
- Codeforces #425 Div2 D
#425 Div2 D 题意 给出一个树形图,每次询问给出三个点,从其中选择两个作为起始点,一个终点,求从两个起始点出发(走最短路)到达终点经过的共同的点最多的数量. 分析 这种树上点与点之间距离有关 ...
- HDU 3966 Aragorn's Story(树链剖分)(线段树区间修改)
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 【贪心】Mixing Milk
题目描述 The Merry Milk Makers company buys milk from farmers, packages it into attractive 1- and 2-Unit ...
- 使用after伪类,配合IE的zoom或者overflow清除浮动
用after伪类实现,兼容多种浏览器:.clearfix:after {content:"."; display:block; height:0; clear:both; visi ...
- 【bzoj1562】【[NOI2009]变换序列】匈牙利算法的性质利用
(上不了p站我要死了,侵权度娘背锅) Description Input Output Sample Input 5 1 1 2 2 1 Sample Output 1 2 4 0 3 HINT 30 ...
- kong流程学习
kong: 根据Nginx的不同执行阶段,kong先执行初始化master和worker进程. init_by_lua_block { require 'resty.core' kong = requ ...
- extjs grid合并单元格
http://blog.csdn.net/kunoy/article/details/7829395 /** * Kunoy * 合并单元格 * @param {} grid 要合并单元格的grid对 ...