鞍山网站建设企业,mysql数据库建设网站,网页在线代理浏览,鞍山网站建设找金航以下文章将显示在我参与的一个项目中#xff0c;我们如何使用Spring的AOP来介绍一些与安全性相关的功能。 这样的概念是为了使用户能够看到一些UI组件#xff0c;他需要具有一定级别的安全特权。 如果不满足该要求#xff0c;则不会显示UIComponent。 让我们看一下项目结构我们如何使用Spring的AOP来介绍一些与安全性相关的功能。 这样的概念是为了使用户能够看到一些UI组件他需要具有一定级别的安全特权。 如果不满足该要求则不会显示UIComponent。 让我们看一下项目结构 然后还有aopApplicationContext.xml ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://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.xsdaop:aspectj-autoproxy /context:annotation-config /context:component-scan base-packagepl.grzejszczak.marcin.aopcontext:exclude-filter typeannotation expressionorg.aspectj.lang.annotation.Aspect//context:component-scanbean classpl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor factory-methodaspectOf/ /beans 现在让我们看一下Spring应用程序上下文中最有趣的几行。 首先我们拥有所有必需的模式-我认为不需要对此进行更深入的解释。 然后我们有 aop:aspectj-autoproxy/ 启用AspectJ支持。 接下来是 context:annotation-config /
context:component-scan base-packagepl.grzejszczak.marcin.aopcontext:exclude-filter typeannotation expressionorg.aspectj.lang.annotation.Aspect/
/context:component-scan 首先我们通过注释打开Spring配置。 然后我们故意排除了由Spring本身将其初始化为Bean的方面。 为什么 因为… bean classpl.grzejszczak.marcin.aop.interceptor.SecurityInterceptor factory-methodaspectOf/ 我们希望自己创建方面并提供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组件扩展的示例只有拥有Admin或Guest角色的用户才能看到。 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 doesnt 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 methods argument check if the class is annotataed with* {link SecurityAnnotation}* * param arguments* return*/private Annotation checkTheAnnotation(Object[] arguments) {Object concreteClass arguments[0];LOGGER.info(Arguments 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;ListRole 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 Arguments 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 Arguments 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 Arguments 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 doesnt 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 Arguments 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 doesnt 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