代码地址如下:
http://www.demodashi.com/demo/12811.html

0.准备工作

注意!!!

本案例数据库相关请下载例子包,内有数据库脚本、EXCEL数据表和详细的设计文档(功能流程图,权限说明,数据表设计,接口设计等)。

0.1运行环境

jdk1.6
maven
tomcat7

0.2知识储备

对SpringMVC框架有所了解
对AOP编程有所了解
对权限管理的逻辑有所了解,思维清晰
本案例中等难度,代码注释较少,有不明白的地方,或者不正确的地方,欢迎联系作者本人或留言。

1.设计思路

1.1功能点

  1. 登录

    1. 防止重复登录
    2. token有效期内自动relogin
  2. 角色管理
    1. 新增角色、修改角色名与角色权限
    2. 删除角色(连带删除节点下的所有角色)
  3. 用户管理
    1. 按用户名模糊查询,按角色名精确查询
    2. 新增、修改、删除用户
  4. 组织结构图
  5. 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项目难点

  1. 对权限管理的理解
  2. 前后端分离的数据交互
  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的权限管理系统(无权限框架)

代码地址如下:
http://www.demodashi.com/demo/12811.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

基于SpringMVC+Ext.js的权限管理系统(无权限框架)的更多相关文章

  1. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(20)-权限管理系统-根据权限获取菜单

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(20)-权限管理系统-根据权限获取菜单 不知不觉到20讲,真是漫长的日子,可惜最近工作挺忙,要不可以有更多 ...

  2. 通用权限管理系统之权限菜单zTree树的展示及移动的处理方法

    在通用权限管理系统中,有很多数据结构是有父子关系的,如组织机构,部门,权限菜单等,在展示的时候,大多数是通过zTree树的形式展现的,如下: 权限菜单展示 这种数据后台输出比较容易处理,参考如下获取某 ...

  3. 《Ext JS模板与组件基本知识框架图----模板》

    最近在整理Ext JS的模板和组件,在参考<Ext JS权威指南>,<Ext JS Web应用程序开发指南>,<Ext JS API>等相关书籍后才写下这篇< ...

  4. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(24)-权限管理系统-将权限授权给角色

    系列目录 过了个年回来,回顾一下,我们上次讲了角色管理,我们这一次来讲将权限授权给角色,这一节也是大家比较关心的.因为我们已经跑通了整个系统,知道权限的流转,我们先来看一张图 这张图主要分要3块,角色 ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(20)-权限管理系统-根据权限获取菜单

    系列目录 不知不觉到20讲,真是漫长的日子,可惜最近工作挺忙,要不可以有更多的时间来更新,多谢大家的一路支持.如果你觉得好,记得帮我点击推荐^-^ 我们在之前已经插入一些真实数据,其中包含了一个用户和 ...

  6. 权限管理系统之项目框架搭建并集成日志、mybatis和分页

    前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据. 一.项目框架 首先要解决的是项目框架问题,搭建什么样的 ...

  7. 零开始:NetCore项目权限管理系统:基础框架搭建

    有兴趣的同学可以一起做 喜欢NetCore的朋友,欢迎加群QQ:86594082 源码地址:https://github.com/feiyit/SoaProJect 新建一个空的解决方案,建立对应的解 ...

  8. spring security 在controller层 方法级别使用注解 @PreAuthorize("hasRole('ROLE_xxx')")设置权限拦截 ,无权限则返回403

    1.前言 以前学习的时候使用权限的拦截,一般都是对路径进行拦截 ,要么用拦截器设置拦截信息,要么是在配置文件内设置拦截信息, spring security 支持使用注解的形式 ,写在方法和接口上拦截 ...

  9. Ext JS 6学习文档–第1章–ExtJS入门指南

    Ext JS 入门指南 前言 本来我是打算自己写一个系列的 ExtJS 6 学习笔记的,因为 ExtJS 6 目前的中文学习资料还很少.google 搜索资料时找到了一本国外牛人写的关于 ExtJS ...

随机推荐

  1. OpenGL入门学习(四)

    http://blog.csdn.net/sun6255028/article/details/5090055 OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式.无论哪种颜色模式,计算 ...

  2. Android Sshd使用

    1. 介绍 因为某些原因, 笔者需要在android上开发,  使用adb比较麻烦, 于是想使用sshd. 推荐的软件是openssh, 其他选择有dropbear, mosh.当然还有其他选择, 如 ...

  3. UVALIVE 2955 Vivian's Problem

    参考: http://blog.csdn.net/acm_cxlove/article/details/7860735 感觉这里需要记录一下 #include <map> #include ...

  4. linux内核情景分析之exit与Wait

    //第一层系统调用 asmlinkage long sys_exit(int error_code) { do_exit((error_code&0xff)<<8); } 其主体是 ...

  5. do_exit——>exit_notify()【转】

    转自:http://blog.csdn.net/sunnybeike/article/details/6907322 版权声明:本文为博主原创文章,未经博主允许不得转载. /* * Send sign ...

  6. 利用Redis生成业务流水号思路

    系统需要生成根据业务类型生成流水号,每天从1开始生成,第二天会清零继续从0开始,流水号格式为: bizCode + date + incr  如:TT-2017112300001. 思路:利用Redi ...

  7. 常用Mysql查询语句

    1.查询数据表中重复记录 select user_name,count(*) as count from user_table group by user_name having count>1 ...

  8. 阿里最新出的图书《码出高效:Java开发手册》宣传手册图片里出了比较搞笑的错误,大家没有发现?

  9. Python的并发并行[2] -> 队列[0] -> queue 模块

    queue 模块 / queue Module 1 常量 / Constants Pass 2 函数 / Function Pass 3 类 / Class 3.1 Queue类 类实例化:queue ...

  10. Python的网络编程[0] -> socket[1] -> socket 模块

    socket 1. 常量 / Constants AF_* 和 SOCK_* 分别属于 AddressFamily 和 SocketType 1.1 AF_*类常量 socket.AF_UNIX:  ...