什么是 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. YAPI接口自动鉴权功能部署详解

    安装准备 以下操作,默认要求自己部署过yapi,最好是部署过yapi二次开发环境. 无论是选择在线安装或者是本地安装,都需要安装client工具. 1.yapi-cli:npm install yap ...

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

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

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

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

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

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

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

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

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

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

  9. 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...

随机推荐

  1. SpringBoot简单(登录/显示/登出)工程下载 附带打包成ROOT.war文件并发布到tomcat里

    下载地址:https://files.cnblogs.com/files/xiandedanteng/SessionShare20191226-1.zip 之前的工程仅能在Eclispe里跑起来,要把 ...

  2. Git——从安装到连接GitHub

    安装Git Windows平台上很轻松的,直接点击地址Git下载进行下载,之后基本就是下一步,安装成功. 在所需要操作的项目下右键,点击"Git Bash Here"弹出Git命令 ...

  3. 编程体系结构(03):Java集合容器

    本文源码:GitHub·点这里 || GitEE·点这里 一.集合容器简介 集合容器是Java开发中最基础API模块,通常用来存储运行时动态创建的元素,基本特点如下: 泛型特点,存储任意类型对象: 动 ...

  4. sql注入 报错注入常用的三种函数

    1.floor()函数 报错原因是 报错的原因是因为rand()函数在查询的时候会执行一次,插入的时候还会执行一次.这就是整个语句报错的关键 前面说过floor(rand(0)*2) 前六位是0110 ...

  5. web网站——理论01

    LAMP的架构以及通信过程 LAMP的架构: LAMP是一个多C/S架构的平台,最初级为web客户端基于TCP/IP通过http协议发起传送,这个请求可能是动态的,也可能是静态的. 所以web服务器通 ...

  6. 3.Strom-并发机制

  7. Docker:一、开始部署第一个Asp.net应用

    工具: docker desktop :一个使用Docker的IDE工具,可以理解为SourceTree,也是使用git的一个桌面化工具: kitematic :配合desctop,用来管理本地的镜像 ...

  8. ip子网掩码计算及子网划分

    为什么要懂 子网掩码计算,及子网划分属于网络基础知识.一般在几个地方会用到: 公司避免产生网络风暴而划分子网,帮助路由器判断对应主机是否在同一个网段中 服务器相互隔离而划分子网,一般机房管理人员规划: ...

  9. 空间向量变换,以及OpenGL的glm库简单应用

    测试项目请查看GitHub库 GLBIproject2/GLBIProject2_2

  10. 文档驱动 —— 表单组件(六):基于AntDV的Form表单的封装,目标还是不写代码

    开源代码 https://github.com/naturefwvue/nf-vue3-ant 也不知道大家是怎么写代码的,这里全当抛砖引玉 为何封装? AntDV非常强大,效果也非常漂亮,功能强大, ...