什么是 AOP

首先我们先了解一下什么是AOP,AOP(Aspect Orient Programming),直译过来就是面向切面编程。AOP是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。那么本次实现的鉴权功能就是将鉴权代码作为切面织入到需要使用鉴权功能的代码上.以下功能需要使用SpringAop的通知功能与自定义注解,对SpringAop及自定义注解不熟悉的同学可以先去了解一下

基于SpringAop通知实现鉴权

实现思路

基本实现思路就是

  • 编写自定义注解作为切点
  • 然后在切面类中编写鉴权逻辑代码
  • 最后在需要鉴权的方法前添加自定义注解

这样在调用添加了鉴权注解的方法时就是先执行鉴权切面类的代码来进行鉴权

鉴权切点类代码示例

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Authority {
AuthorityType value() default AuthorityType.Validate; FuncIdType[] funcIdTypes() default {}; ModuleIdType[] moduleIdTypes() default {};
}

鉴权切面类代码示例

@Aspect
@Component
public class AuthorityAspect {
private static Logger logger = LoggerFactory.getLogger(SystemLogAspect.class); // 日志切点
@Pointcut("@annotation(com.hzjd.jdmp.annotation.Authority)")
public void executeService() {
}
// 验证是否具有该功能的权限
private boolean validateFunc(FuncIdType[] funcIdTypes) {
HttpSession session = ActionStackManager.getSession();
SessionStackData sessionStackData = SessionStackData.getSessionStackData(session);
if (sessionStackData.getRl() == null) {
return false;
}
for (int i = 0; i < funcIdTypes.length; i++) {
if (sessionStackData.getRl().haveRight(funcIdTypes[i])) {
return true;
}
}
return false;
} // 验证是否具有该模块的权限
private boolean validateModule(ModuleIdType[] moduleIdTypes) {
HttpSession session = ActionStackManager.getSession();
SessionStackData sessionStackData = SessionStackData.getSessionStackData(session);
if (sessionStackData.getRm() == null) {
return false;
}
for (int i = 0; i < moduleIdTypes.length; i++) {
if (sessionStackData.getRm().haveRight(moduleIdTypes[i])) {
return true;
}
}
return false;
} private Object toError(Boolean responseBody) {
if (responseBody) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("success", false);
map.put("msg", "您没有操作此功能的权限");
String json = JsonUtil.toJsonObject(map).toString();
HttpServletResponse response = ActionStackManager.getResponse();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
try {
response.getWriter().write(json);
} catch (IOException e) {
e.printStackTrace();
}
return null;
} else {
return "errauth";
}
} private Object toLogin() {
HttpServletResponse response = ActionStackManager.getResponse();
String loginUrl = ActionStackManager.getRequest().getContextPath() + "/index";
String str = "<script language='javascript'>alert('会话过期,请重新登录');" + "window.top.location.href='" + loginUrl
+ "';</script>";
response.setContentType("text/html;charset=UTF-8");// 解决中文乱码
PrintWriter writer;
try {
writer = response.getWriter();
writer.write(str);
writer.flush();
} catch (IOException e) {
}
return null;
} @Around(value = "executeService()")
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Signature signature = proceedingJoinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
Method realMethod = proceedingJoinPoint.getTarget().getClass()
.getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes());
Authority authority = targetMethod.getAnnotation(Authority.class);
Class<?> clazz = targetMethod.getClass();
logger.debug("realMethod:" + realMethod.getName());
logger.debug("realMethod Class:" + realMethod.getDeclaringClass().getSimpleName());
boolean pass = false;
boolean responseBody = targetMethod.isAnnotationPresent(ResponseBody.class);
if (clazz != null && targetMethod != null) {
if (authority != null) {
if (AuthorityType.NoValidate == authority.value()) {
logger.debug("标记为不验证,放行");
// 标记为不验证,放行
pass = true;
} else if (AuthorityType.NoAuthority == authority.value()) {
logger.debug("不验证权限,验证是否登录");
// 不验证权限,验证是否登录
pass = BaseSearchForm.getLoginUser() != null;
if (!pass) {
return toLogin();
}
} else {
if (BaseSearchForm.getLoginUser() != null) {
logger.debug("正在验证权限");
if (authority.funcIdTypes() != null && authority.funcIdTypes().length > 0) {
pass = validateFunc(authority.funcIdTypes());
}
if (!pass) {
if (authority.moduleIdTypes() != null && authority.moduleIdTypes().length > 0) {
pass = validateModule(authority.moduleIdTypes());
}
}
} else {
return toLogin();
}
}
}
}
if (!pass) {
return toError(responseBody);
} else {
logger.debug("验证权限通过");
}
Object obj = proceedingJoinPoint.proceed();
return obj;
}
}

实现方法示例

@RequestMapping(value = "/updateOwerPwd")
@SystemLogAnnotation
@Authority(value = AuthorityType.NoAuthority)
public String updateOwerPwd(ModelMap model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
ActionStackManager.initNewData(model, request, response);
try {
HttpSession session = ActionStackManager.getRequest().getSession();
SysUser sysUser = SessionStackData.getSessionStackData(session).getSysUser();
if (sysUser == null) {
session.invalidate();
return forward("login");
}
sysUser = sysUserService.findById(sysUser.getUserid());
if (sysUser == null) {
session.invalidate();
return forward("login");
}
String oldpassword = getRequestParameter("oldpwd");
String password = getRequestParameter("pwd1");
if (!sysUser.getPassword().equals(MD5Utils.getBASE64MD5(oldpassword)))
return forwardError("旧密码输入不正确,修改密码失败!");
sysUser.setPassword(MD5Utils.getBASE64MD5(password));
if (!sysUserService.update(sysUser))
return forwardError("修改密码失败!");
return forward("includes/main");
} catch (Exception e) {
logError(e);
return forwardError(e);
} finally {
ActionStackManager.removeThreadData();
}
}

基于SpringAop的鉴权功能的更多相关文章

  1. 基于token机制鉴权架构

    常见的鉴权方式有两种,一种是基于session,另一种是基于token方式的鉴权,我们来浅谈一下两种 鉴权方式的区别. 两种鉴权方式对比 session 安全性:session是基于cookie进行用 ...

  2. [原创]SpringSecurity控制授权(鉴权)功能介绍

    1.spring security 过滤器链 ​ spring security中的除了用户登录校验相关的过滤器,最后还包含了鉴权功能的过滤器,还有匿名资源访问的过滤器链,相关的图解如下: 2.控制授 ...

  3. 「快学springboot」集成Spring Security实现鉴权功能

    Spring Security介绍 Spring Security是Spring全家桶中的处理身份和权限问题的一员.Spring Security可以根据使用者的需要定制相关的角色身份和身份所具有的权 ...

  4. Session, Token, OAuth 鉴权那些事儿

    鉴权那些事 整体思路 无论什么样的服务, Web 服务总是不能绕开鉴权这个话题的, 通过有效的鉴权手段来保护网站数据, 来为特定用户提供服务. 整体来说, 有三种方式: Session-Cookie ...

  5. 认证鉴权与API权限控制在微服务架构中的设计与实现(四)

    引言: 本文系<认证鉴权与API权限控制在微服务架构中的设计与实现>系列的完结篇,前面三篇已经将认证鉴权与API权限控制的流程和主要细节讲解完.本文比较长,对这个系列进行收尾,主要内容包括 ...

  6. EasyNVR摄像机网页H5全平台无插件直播流媒体播放服务二次开发之接口鉴权示例讲解

    背景需求 EasyNVR的使用者应该都清楚的了解到,EasyNVR一个强大的功能就是可以进行全平台的无插件直播.主要原因在于rtsp协议的视频流(默认是需要插件才可以播放的)经由EasyNVR处理可以 ...

  7. 深入理解k8s中的访问控制(认证、鉴权、审计)流程

    Kubernetes自身并没有用户管理能力,无法像操作Pod一样,通过API的方式创建/删除一个用户实例,也无法在etcd中找到用户对应的存储对象. 在Kubernetes的访问控制流程中,用户模型是 ...

  8. Mongodb 认证鉴权那点事

    [TOC] 一.Mongodb 的权限管理 认识权限管理,说明主要概念及关系 与大多数数据库一样,Mongodb同样提供了一套权限管理机制. 为了体验Mongodb 的权限管理,我们找一台已经安装好的 ...

  9. vue项目中的登录鉴权

    用vue做一个简单的登录鉴权功能. 项目目录结构如下: Login 组件 登录成功后做本地存储和store存储,并进行跳转. Login.vue关键代码: async handleLogin(e) { ...

随机推荐

  1. PostgreSQL表空间、模式、表、用户/角色之间的关系

    PostgreSQL表空间.模式.表.用户/角色之间的关系是本文我们主要要介绍的内容,表空间,数据库,模式,表,用户,角色之间的关系到底是怎样的呢?接下来我们就开始介绍这一过程. 实验出角色与用户的关 ...

  2. AngularJS 中文资料+工具+库+Demo 大搜集

    中文学习资料: 中文资料且成系统的就这么多,优酷上有个中文视频. http://www.cnblogs.com/lcllao/archive/2012/10/18/2728787.html   翻译的 ...

  3. java核心技术记录之java术语

    术语名 缩写 解释 Java Development Kit JDK 编写java程序的程序员使用的软件 Java Runtime Environment JRE 运行java程序的用户使用的软件 S ...

  4. POJ 2516 最小费用最大流

    每一种货物都是独立的,分成k次最小费用最大流即可! 1: /** 2: 因为e ==0 所以 pe[v] pe[v]^1 是两条相对应的边 3: E[pe[v]].c -= aug; E[pe[v]^ ...

  5. ASP.NET html转图片

    using System.IO; using System.Drawing; using System.Threading; using System.Windows.Forms; public cl ...

  6. (2012年旧文)纪念史蒂夫乔布斯---IT界的普罗米修斯

    谈苹果与乔布斯系列一  IT界的普罗米修斯 纪念PC界的先驱 史蒂夫乔布斯 2012-4-5 清明节,纪念IT时代的开创人—伟大的史蒂夫 乔布斯. 没有乔布斯,计算机还是属于一群科技人士的工具,没有漂 ...

  7. HTTP数据包头解析(简单清楚)

    [转]HTTP请求模型和头信息参考 参考: http://blog.csdn.net/baggio785/archive/2006/04/13/661410.aspx模型: http://blog.c ...

  8. MySQL各种日期类型与整型(转)

    日期类型 存储空间 日期格式 日期范围 datetime 8 bytes YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 t ...

  9. 電腦清理緩存bat文件源碼

    @echo off echo 正在清除系統垃圾文件,請稍等 ...... del /f /s /q %systemdrive%\*.tmp del /f /s /q %systemdrive%\*._ ...

  10. 交换机的vlan文章

    https://blog.csdn.net/standmyground/article/details/3933364 大家知道,交换机会把广播报文(目的mac地址全1的报文)和未知单播报文从所有端口 ...