以下文章将显示在我参与的一个项目中,我们如何使用Spring的AOP来介绍一些与安全性相关的功能。 这样的概念是为了使用户能够看到一些UI组件,他需要具有一定级别的安全特权。 如果不满足该要求,则不会显示UIComponent。 让我们看一下项目结构:

然后还有aopApplicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><aop:aspectj-autoproxy /><context:annotation-config /><context:component-scan base-package="pl.grzejszczak.marcin.aop"><context:exclude-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/></context:component-scan><bean class="pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor" factory-method="aspectOf"/> </beans>

现在,让我们看一下Spring应用程序上下文中最有趣的几行。 首先,我们拥有所有必需的模式-我认为不需要对此进行更深入的解释。 然后我们有:

<aop:aspectj-autoproxy/>

启用@AspectJ支持。 接下来是

<context:annotation-config />
<context:component-scan base-package="pl.grzejszczak.marcin.aop"><context:exclude-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>

首先,我们通过注释打开Spring配置。 然后,我们故意排除了由Spring本身将其初始化为Bean的方面。 为什么? 因为…

<bean class="pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor" factory-method="aspectOf"/>

我们希望自己创建方面,并提供factory-method =” aspectOf”。 这样,我们的方面将包含在我们的bean的自动装配过程中-因此,所有带有@Autowired注释的字段都将注入bean。 现在让我们继续执行代码:

UserServiceImpl.java

package pl.grzejszczak.marcin.aop.service;import org.springframework.stereotype.Service;import pl.grzejszczak.marcin.aop.type.Role;
import pl.grzejszczak.marcin.aop.user.UserHolder;@Service
public class UserServiceImpl implements UserService {private UserHolder userHolder;@Overridepublic UserHolder getCurrentUser() {return userHolder;}@Overridepublic void setCurrentUser(UserHolder userHolder) {this.userHolder = userHolder;}@Overridepublic Role getUserRole() {if (userHolder == null) {return null;}return userHolder.getUserRole();}
}

UserServiceImpl类正在模仿一种服务,该服务将从数据库或当前应用程序上下文中获取当前用户信息。

UserHolder.java

package pl.grzejszczak.marcin.aop.user;import pl.grzejszczak.marcin.aop.type.Role;public class UserHolder {private Role userRole;public UserHolder(Role userRole) {this.userRole = userRole;}public Role getUserRole() {return userRole;}public void setUserRole(Role userRole) {this.userRole = userRole;}
}

这是一个简单的持有人类,其中包含有关当前用户角色的信息。

角色.java

package pl.grzejszczak.marcin.aop.type;public enum Role {ADMIN("ADM"), WRITER("WRT"), GUEST("GST");private String name;private Role(String name) {this.name = name;}public static Role getRoleByName(String name) {for (Role role : Role.values()) {if (role.name.equals(name)) {return role;}}throw new IllegalArgumentException("No such role exists [" + name + "]");}public String getName() {return this.name;}@Overridepublic String toString() {return name;}
}

角色是一个枚举,它为管理员作家来宾定义了一个角色。

UIComponent.java

package pl.grzejszczak.marcin.aop.ui;public abstract class UIComponent {protected String componentName;protected String getComponentName() {return componentName;}}

一些UI组件的具体实现的抽象。

SomeComponentForAdminAndGuest.java

package pl.grzejszczak.marcin.aop.ui;import pl.grzejszczak.marcin.aop.annotation.SecurityAnnotation;
import pl.grzejszczak.marcin.aop.type.Role;@SecurityAnnotation(allowedRole = { Role.ADMIN, Role.GUEST })
public class SomeComponentForAdminAndGuest extends UIComponent {public SomeComponentForAdminAndGuest() {this.componentName = "SomeComponentForAdmin";}public static UIComponent getComponent() {return new SomeComponentForAdminAndGuest();}
}

此组件是UI组件扩展的示例,只有拥有AdminGuest角色的用户才能看到。

SecurityAnnotation.java

package pl.grzejszczak.marcin.aop.annotation;import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;import pl.grzejszczak.marcin.aop.type.Role;@Retention(RetentionPolicy.RUNTIME)
public @interface SecurityAnnotation {Role[] allowedRole();
}

定义可以创建此组件的角色的注释。

UIFactoryImpl.java

package pl.grzejszczak.marcin.aop.ui;import org.apache.commons.lang.NullArgumentException;
import org.springframework.stereotype.Component;@Component
public class UIFactoryImpl implements UIFactory {@Overridepublic UIComponent createComponent(Class<? extends UIComponent> componentClass) throws Exception {if (componentClass == null) {throw new NullArgumentException("Provide class for the component");}return (UIComponent) Class.forName(componentClass.getName()).newInstance();}
}

给定扩展UIComponent的对象类的工厂类将返回给定UIComponent的新实例。

SecurityInterceptor.java

package pl.grzejszczak.marcin.aop.interceptor;import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;
import java.util.List;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;import pl.grzejszczak.marcin.aop.annotation.SecurityAnnotation;
import pl.grzejszczak.marcin.aop.service.UserService;
import pl.grzejszczak.marcin.aop.type.Role;
import pl.grzejszczak.marcin.aop.ui.UIComponent;@Aspect
public class SecurityInterceptor {private static final Logger LOGGER = LoggerFactory.getLogger(SecurityInterceptor.class);public SecurityInterceptor() {LOGGER.debug("Security Interceptor created");}@Autowiredprivate UserService userService;@Pointcut("execution(pl.grzejszczak.marcin.aop.ui.UIComponent pl.grzejszczak.marcin.aop.ui.UIFactory.createComponent(..))")private void getComponent(ProceedingJoinPoint thisJoinPoint) {}@Around("getComponent(thisJoinPoint)")public UIComponent checkSecurity(ProceedingJoinPoint thisJoinPoint) throws Throwable {LOGGER.info("Intercepting creation of a component");Object[] arguments = thisJoinPoint.getArgs();if (arguments.length == 0) {return null;}Annotation annotation = checkTheAnnotation(arguments);boolean securityAnnotationPresent = (annotation != null);if (securityAnnotationPresent) {boolean userHasRole = verifyRole(annotation);if (!userHasRole) {LOGGER.info("Current user doesn't have permission to have this component created");return null;}}LOGGER.info("Current user has required permissions for creating a component");return (UIComponent) thisJoinPoint.proceed();}/*** Basing on the method's argument check if the class is annotataed with* {@link SecurityAnnotation}* * @param arguments* @return*/private Annotation checkTheAnnotation(Object[] arguments) {Object concreteClass = arguments[0];LOGGER.info("Argument's class - [{}]", new Object[] { arguments });AnnotatedElement annotatedElement = (AnnotatedElement) concreteClass;Annotation annotation = annotatedElement.getAnnotation(SecurityAnnotation.class);LOGGER.info("Annotation present - [{}]", new Object[] { annotation });return annotation;}/*** The function verifies if the current user has sufficient privilages to* have the component built* * @param annotation* @return*/private boolean verifyRole(Annotation annotation) {LOGGER.info("Security annotation is present so checking if the user can use it");SecurityAnnotation annotationRule = (SecurityAnnotation) annotation;List<Role> requiredRolesList = Arrays.asList(annotationRule.allowedRole());Role userRole = userService.getUserRole();return requiredRolesList.contains(userRole);}
}

这是在执行函数createComponent的切入点处定义的方面
UIFactory接口。 在“ 环绕” 建议中,存在一种逻辑,该逻辑首先检查将什么样的参数传递给方法createComponent(例如SomeComponentForAdminAndGuest.class)。 接下来,检查此类是否用SecurityAnnotation进行注释,如果是,它将检查创建组件所需的角色类型。 然后,它检查当前用户(从UserService到UserHolder的Roles)是否具有呈现组件所需的角色。 如果是这样的话 调用thisJoinPoint.proceed(),实际上返回扩展UIComponent的类的对象。 现在让我们对其进行测试-SpringJUnit4ClassRunner来了

AopTest.java

package pl.grzejszczak.marcin.aop;import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import pl.grzejszczak.marcin.aop.service.UserService;
import pl.grzejszczak.marcin.aop.type.Role;
import pl.grzejszczak.marcin.aop.ui.SomeComponentForAdmin;
import pl.grzejszczak.marcin.aop.ui.SomeComponentForAdminAndGuest;
import pl.grzejszczak.marcin.aop.ui.SomeComponentForGuest;
import pl.grzejszczak.marcin.aop.ui.SomeComponentForWriter;
import pl.grzejszczak.marcin.aop.ui.UIFactory;
import pl.grzejszczak.marcin.aop.user.UserHolder;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:aopApplicationContext.xml" })
public class AopTest {@Autowiredprivate UIFactory uiFactory;@Autowiredprivate UserService userService;@Testpublic void adminTest() throws Exception {userService.setCurrentUser(new UserHolder(Role.ADMIN));Assert.assertNotNull(uiFactory.createComponent(SomeComponentForAdmin.class));Assert.assertNotNull(uiFactory.createComponent(SomeComponentForAdminAndGuest.class));Assert.assertNull(uiFactory.createComponent(SomeComponentForGuest.class));Assert.assertNull(uiFactory.createComponent(SomeComponentForWriter.class));}
}

和日志:

pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:26 Security Interceptor created
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:38 Intercepting creation of a component
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:48 Argument's class - [[class pl.grzejszczak.marcin.aop.ui.SomeComponentForAdmin]]
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:54 Annotation present - [@pl.grzejszczak.marcin.aop.annotation.SecurityAnnotation(allowedRole=[ADM])]
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:57 Security annotation is present so checking if the user can use it
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:70 Current user has required permissions for creating a component
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:38 Intercepting creation of a component
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:48 Argument's class - [[class pl.grzejszczak.marcin.aop.ui.SomeComponentForAdminAndGuest]]
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:54 Annotation present - [@pl.grzejszczak.marcin.aop.annotation.SecurityAnnotation(allowedRole=[ADM, GST])]
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:57 Security annotation is present so checking if the user can use it
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:70 Current user has required permissions for creating a component
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:38 Intercepting creation of a component
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:48 Argument's class - [[class pl.grzejszczak.marcin.aop.ui.SomeComponentForGuest]]
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:54 Annotation present - [@pl.grzejszczak.marcin.aop.annotation.SecurityAnnotation(allowedRole=[GST])]
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:57 Security annotation is present so checking if the user can use it
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:66 Current user doesn't have permission to have this component created
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:38 Intercepting creation of a component
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:48 Argument's class - [[class pl.grzejszczak.marcin.aop.ui.SomeComponentForWriter]]
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:54 Annotation present - [@pl.grzejszczak.marcin.aop.annotation.SecurityAnnotation(allowedRole=[WRT])]
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:57 Security annotation is present so checking if the user can use it
pl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor:66 Current user doesn't have permission to have this component created

单元测试表明,对于给定的Admin角色,仅创建了前两个组件,而对于其他两个,则返回null(由于用户没有适当的权限)。 这就是在我们的项目中,我们如何使用Spring的AOP创建一个简单的框架,该框架将检查用户是否可以创建给定的组件。 由于对这些方面进行了编程,因此不必记住编写任何与安全相关的代码,因为它将为他完成。

参考: 安全性中的Spring AOP –通过我们的JCG合作伙伴 Marcin Grzejszczak(位于Blog上)上的代码瘾君子博客来控制UI组件的创建 。

翻译自: https://www.javacodegeeks.com/2013/04/spring-aop-in-security-controlling-creation-of-ui-components-via-aspects.html

安全性中的Spring AOP –通过方面控制UI组件的创建相关推荐

  1. spring aop组件_安全性中的Spring AOP –通过方面控制UI组件的创建

    spring aop组件 以下文章将显示在我参与的一个项目中,我们如何使用Spring的AOP来介绍一些与安全性相关的功能. 这样的概念是,为了使用户能够看到某些UI组件,他需要具有一定级别的安全特权 ...

  2. J2EE中使用Spring AOP框架和EJB组件

    快速发展的开发人员社区.对各种后端技术(包括JMS.JTA.JDO.Hibernate.iBATIS等等)的支持,以及(更为重要的)非侵入性的轻量级IoC容器和内置的AOP运行时,这些因素使得Spri ...

  3. J2EE中使用Spring AOP框架和EJB组件(1)

    J2EE中使用Spring AOP框架和EJB组件(1) [@more@]本文介绍了一种把J2EE应用程序中的EJB转换为Spring托管组件的方法,以及转换之后可以采用的强大技术.它还给出了几个实际 ...

  4. J2EE中使用Spring AOP框架和EJB组件(6)

    J2EE中使用Spring AOP框架和EJB组件(6) [@more@] 组合和链接通知 我们已经使用了一个简单的拦截器通知来实现附加的逻辑,并且将其当作一个独立的组件进行了测试.当应该在不进行修改 ...

  5. 【鸿蒙 HarmonyOS】Ability 中使用纯代码绘制布局及 UI 组件

    文章目录 一.Ability 与 Slice 简介 二.Ability 中使用纯代码绘制布局及 UI 组件 三.Ability 中使用纯代码绘制布局及 UI 组件代码示例 四.GitHub 地址 一. ...

  6. 一分钟搞定Spring AOP实现权限控制

    Spring Aop就是我们常说的面向切面编程,它和IOC构成了spring体系的两大核心,玩明白了这两个,spring就算玩会了.. spring aop可以干很多事,他就类似于拦截器,能在你的目标 ...

  7. 基于Spring AOP实现权限控制

    基于Spring AOP实现一个简单的接口权限 1.定义自定义注解 //注解的作用类型:方法.类 @Target({ElementType.METHOD,ElementType.TYPE}) @Ret ...

  8. 在 Spring Boot 中使用 Spring AOP 和 AspectJ 来测量方法的执行时间

    原文链接:https://dzone.com/articles/logging-average-method-execution-times-via-aspectj 作者:Murat Derman 译 ...

  9. 在Eclipse RCP中使用Spring AOP/ProxyFactory的问题

    也许你还没有在RCP中用过SPRING,也许你用过,但没有遇到什么问题,那是因为你只用了简单的IOC,而没有用到AOP或是FactoryBean,因此,您并没有碰到什么问题,但一些很简单的需求导致我们 ...

最新文章

  1. win 64位系统安装带有c编写的python模块出现ValueError: [u'path']解决
  2. ScrollView child layout ([alignItems]) 错误
  3. Cmake常用基本命令复习
  4. 实战|QUIC协议助力腾讯业务提速30%
  5. 这个 HTTP 实战项目,帮你理清 Go 网络编程的底层逻辑
  6. foss测试_FOSS的业务真的是社区软件吗?
  7. OpenStack_Swift源代码分析——Ring基本原理及一致性Hash算法
  8. 破解网站发布系统 ASP生成静态页面方法
  9. Tomcat------如何配置域名和80端口
  10. 提取win11最新等线字体1.18制作的magisk模块,有常规,加粗,和细体三个字重。
  11. zblog php主题,天兴工作室:zblogphp视频站主题(新增会员中心+盈利系统)
  12. 外贸工具WhatsApp
  13. Anaconda虚拟环境中,让Python3使用ROS的cv_bridge
  14. bcc服务器搭建网站,如何用云服务器bcc建站
  15. 网络攻击与防御技术期中习题
  16. 【建站教程】万网域名使用万网\QQ企业邮箱,设置解析方法
  17. 原神倾听木簧笛的八音曲寻找缺失的石头怎么做
  18. 全面解析马斯克的产业帝国
  19. 《纸牌屋》造神:大数据是非
  20. AI机器人系统工作中是如何识别空号的

热门文章

  1. centos7离线安装oracle11g,CentOS 7.5离线安装Oracle 11gR2
  2. python弹出窗口 闪烁_Python。得到闪烁/闪烁的窗口
  3. gpu超算算法_超算安装GPU-based软件 (以pytorch为例)
  4. pre1-flink理论-批处理与流处理+简单示例
  5. mybatis-启动源码分析
  6. camel apache_Apache Camel 3 –新增功能前10名
  7. cli parser_Java命令行界面(第27部分):cli-parser
  8. intellij远程调试_IntelliJ中的远程调试Wildfly应用程序
  9. 基于docker微服务架构_使用基于微服务的流架构更好地进行大规模的复杂事件处理(第1部分)...
  10. 动态代码生成 静态代码生成_将速度提升到自己的个人代码生成器中