jdk1.5中annotation的应用(1)--授权控制

来源:互联网 发布:广州大数据行业协会 编辑:程序博客网 时间:2024/05/16 09:49

做授权控制时不仅仅要用户无法访问的连接不能看到,还要阻止用户通过其他手段得到连接地址而直接调用连接。因此授权控制时还必须防止用户执行jsp、servlet、以及WebService等等所有需要授权验证的服务。
为了做到这一点就必须在用户的入口处做授权校验,如jsp、servlet(struts的Action)等等(授权到底放在何处校验合适,web接口层还是业务的facade层?)。

实现后实现的范例代码:
 @Authorizations(authorizations = {
   @Authorization(rights = { "AccountMatchingRuler" }, test = "${param.rulerType=='AccountMatchingRuler'}"),
   @Authorization(rights = { "IpMatchingRuler","Edit" }, test = "${param.rulerType=='IpMatchingRuler'}",type=AuthorizationElement.anyOne) })
 public ActionForward doExecute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)
上面的意思是如果el表达式${param.rulerType=='AccountMatchingRuler'}判断为真怎校验当前用户是否有权限执行AccountMatchingRuler
如果${param.rulerType=='IpMatchingRuler'}为真,则当前用户必须具有执行IpMatchingRuler或者Edit的权限,其中之所有是具有其中一个即可执行,因为type
配置的是AuthorizationElement.anyOne,其意思指"任意一个",还有其他规则:all指必须全部具有;notAnyOne指不能包含其中任何一个。
只要任意一个Authorization执行校验成功则授权通过。授权通过则可以执行该方法。

在JSP中使用标签,范例代码如下:
确定该JSP能否执行
<authorization:authorizations>
 <authorization:authorization rights="businessOperation"/>
</authorization:authorizations>
确定标签体中的内容是否显示(其实质是标签体是否执行,Skip_body还是evel_body)
<authorization:authorizationShow rights="addRole">
 <div name="item"><html:link action="/addRolePre" target="content" styleClass="menu_li" onclick="clickObject(${pageScope.showObjNum-1},${pageScope.itemNum})">添加岗位</html:link></div>   
 <c:set var="itemNum" value="${pageScope.itemNum+1}" scope="page"/>
</authorization:Show>
其配置和上面类似。
 
判断能否执行的核心代码如下:

 public static boolean authorization(Class _class, String methodName,
   Class[] paramters, String[] rightsForOperator)
   throws NoSuchMethodException {
  // 得到事件函数
  Method eventMethod = _class.getMethod(event, paramters);
  Authorization annotation = eventMethod
    .getAnnotation(Authorization.class);
  return authorization(annotation, rightsForOperator);
 }

 public static boolean authorization(Authorization annotation,
   String[] rightsForOperator) {
  if (annotation != null) {
   String[] rights = annotation.rights();
   AuthorizationElement type = annotation.type();
   return authorization(rights, type, rightsForOperator);
  }
  return true;
 }

 public static boolean authorization(String[] rightRequired,
   AuthorizationElement type, String[] rightsForOperator) {
  if (rightRequired == null || type == null || rightsForOperator == null) {
   return false;
  }
  if (logger.isDebugEnabled()) {
   StringBuffer buffer = new StringBuffer();
   buffer.append("rightRequired:");
   for (String a : rightRequired) {
    buffer.append(a).append(",");
   }
   buffer.append("/ttype:").append(type);
   for (String a : rightsForOperator) {
    buffer.append(a).append(",");
   }
   logger.debug(buffer);
  }
  List<String> roleNamesList = Arrays.asList(rightsForOperator);
  if (type == AuthorizationElement.all) {
   // 当前拥有的角色不存在任何一个则失败
   for (String s : rightRequired) {
    if (!roleNamesList.contains(s)) {
     return false;
    }
   }
  }
  if (type == AuthorizationElement.anyOne) {
   for (String s : rightRequired) {
    if (roleNamesList.contains(s)) {
     return true;
    }
   }
   return false;
  }
  if (type == AuthorizationElement.notAnyOne) {
   // 当前拥有的角色是列表中的任何一个
   for (String s : rightRequired) {
    if (roleNamesList.contains(s)) {
     return false;
    }
   }
  }
  return true;
 } 
 
struts的Action,业务中的Action继承该BaseAction即可获得授权控制
public abstract class BaseAction extends Action {

 private Authorizations authorizationsAnnotation;

 private Authorization authorizationAnnotation;

 private IRightDiscover rightDiscover = DefaultRightDiscover.getInstance();

 protected BaseAction() {
  Method doExecuteMethod = null;
  try {
   // 得到方法
   doExecuteMethod = this.getClass()
     .getMethod(
       "doExecute",
       new Class[] { ActionMapping.class,
         ActionForm.class, HttpServletRequest.class,
         HttpServletResponse.class });
   // 得到AuthorizationsAnnotation
   this.authorizationsAnnotation = doExecuteMethod
     .getAnnotation(Authorizations.class);
   this.authorizationAnnotation = doExecuteMethod
     .getAnnotation(Authorization.class);
  } catch (SecurityException e) {
   throw new RuntimeException(e);
  } catch (NoSuchMethodException e) {
   throw new RuntimeException(e);
  }
 }

 @Override
 public final ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception {
  // 如果该方法没有配置Authorizations annotation,则认为不验证,否则则根据配置验证
  JspFactory jspxFactory = JspFactory.getDefaultFactory();
  PageContext pageContext = jspxFactory.getPageContext(getServlet(),
    request, response, null, true, 8192, true);
  if (authorizationsAnnotation != null) {
   // 得到当前操作员所拥有的所有权限
   String[] currentRights = rightDiscover.getRights(request);
   if (currentRights == null) {
    currentRights = new String[] {};
   }
   // 得到所配置的所有Authorization annotation
   Authorization[] a = authorizationsAnnotation.authorizations();
   for (int i = 0; i < a.length; i++) {
    // 使用el确定是执行哪一个Authorization
    if (((Boolean) pageContext.getExpressionEvaluator().evaluate(
      a[i].test(), Boolean.class,
      pageContext.getVariableResolver(), null))
      .booleanValue()) {
     // 验证权限
     if (AuthorizationUtil.authorization(a[i], currentRights)) {
      return doExecute(mapping, form, request, response);
     } else {
      throw new AuthorizationException(this.getClass()
        .getName());
     }
    }
   }
  }
  if (authorizationAnnotation != null) {
   // 得到当前操作员所拥有的所有权限
   String[] currentRights = rightDiscover.getRights(request);
   if (currentRights == null) {
    currentRights = new String[] {};
   }
   if (((Boolean) pageContext.getExpressionEvaluator().evaluate(
     authorizationAnnotation.test(), Boolean.class,
     pageContext.getVariableResolver(), null)).booleanValue()) {
    // 验证权限
    if (AuthorizationUtil.authorization(authorizationAnnotation,
      currentRights)) {
     return doExecute(mapping, form, request, response);
    } else {
     throw new AuthorizationException(this.getClass().getName());
    }
   }
  }
  // 如果没有配置Authorizations annotation或者没有找到应该执行哪一个Authorization
  // annotation则表示通过授权
  return doExecute(mapping, form, request, response);
 }

 @Override
 public final ActionForward execute(ActionMapping arg0, ActionForm arg1,
   ServletRequest arg2, ServletResponse arg3) throws Exception {
  return super.execute(arg0, arg1, arg2, arg3);
 }

 public abstract ActionForward doExecute(ActionMapping mapping,
   ActionForm form, HttpServletRequest request,
   HttpServletResponse response) throws Exception;

 public void setRightDiscover(IRightDiscover rightDiscover) {
  this.rightDiscover = rightDiscover;
 }
}

标签的实现代码相对要简单得多 

下次要介绍的是使用Annotation实现DAO层的无代码编程:类似于jdbc4.0内的模式

原创粉丝点击