代码地址如下:
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. Linux中断(interrupt)子系统之五:软件中断(softIRQ)【转】

    转自:http://blog.csdn.net/droidphone/article/details/7518428 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 软件中 ...

  2. 向PE文件中空白处添加代码

    // mem.cpp : 定义控制台应用程序的入口点. //PE文件从文件加载到内存,再从内存读取,然后存盘到文件 #include "stdafx.h" #include < ...

  3. (3)PHP环境搭建和使用

    一.php开发环境 php开发的环境组件一般需要 apache(iis)+mysql+php 可以自己搭建环境或者用别人把这几项集成好的软件,自己搭建的环境配置起来麻烦但可以选择任意版本,集成的软件安 ...

  4. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

  5. JQuery里面的下啦菜单

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  6. (转)NSString 类的使用

    官网连接地址:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Strings/Articles/Creat ...

  7. CSS 标准发布流程

    随着 CSS 3 的广泛应用,很多新的 CSS 属性层出不穷,有很多陌生的 CSS 属性出现,所以经常需要去学习新的 CSS 属性.新的属性往往介绍文章不多,所以有时候就需要去看看官方文档,此时会发现 ...

  8. [BZOJ 1509] 逃学的小孩

    Link: BZOJ 1509 传送门 Solution: 一开始受样例影响又犯了想当然的毛病……图中的C点不一定在直径上! 3次$dfs$求出树的直径及直径的两个端点$rt1,rt2$到每个点的距离 ...

  9. Oracle提示密码快过期的解决办法

    今天在使用ORACLE时报出如下错误:ORA-28002: the password will expire within 7 days================================ ...

  10. 学习Flash 3D图形图像知识的网络资源集合

    1. 华中科技大学计算机学院开放式课程--计算机图形学 http://cs.hust.edu.cn/webroot/courses/csgraphics/index.php 2.深入Stage3D_7 ...