/** * 返回该Controller的所有访问控制注解 * * @return */ private List<Annotation> getAuthzAnnotations(Class<? extends Controller> targetClass) { List<Annotation> annotations = new ArrayList<Annotation>(); for (Class<? extends Annotation> annClass : AUTHZ_ANNOTATION_CLASSES) { Annotation a = targetClass.getAnnotation(annClass); if (a != null) { annotations.add(a); } } return annotations; }
/** 启动插件 */ @Override public boolean start() { Set<String> excludedMethodName = buildExcludedMethodName(); ConcurrentMap<String, AuthzHandler> authzMaps = new ConcurrentHashMap<String, AuthzHandler>(); // 逐个访问所有注册的Controller,解析Controller及action上的所有Shiro注解。 // 并依据这些注解,actionKey提前构建好权限检查处理器。 for (Entry<String, Class<? extends Controller>> entry : routes.getEntrySet()) { Class<? extends Controller> controllerClass = entry.getValue(); String controllerKey = entry.getKey(); // 获取Controller的所有Shiro注解。 List<Annotation> controllerAnnotations = getAuthzAnnotations(controllerClass); // 逐个遍历方法。 Method[] methods = controllerClass.getMethods(); for (Method method : methods) { // 排除掉Controller基类的所有方法,并且只关注没有参数的Action方法。 if (!excludedMethodName.contains(method.getName()) && method.getParameterTypes().length == 0) { // 若该方法上存在ClearShiro注解,则对该action不进行访问控制检查。 if (isClearShiroAnnotationPresent(method)) { continue; } // 获取方法的所有Shiro注解。 List<Annotation> methodAnnotations = getAuthzAnnotations(method); // 依据Controller的注解和方法的注解来生成访问控制处理器。 AuthzHandler authzHandler = createAuthzHandler(controllerAnnotations, methodAnnotations); // 生成访问控制处理器成功。 if (authzHandler != null) { // 构建ActionKey,参考ActionMapping中实现 String actionKey = createActionKey(controllerClass, method, controllerKey); // 添加映射 authzMaps.put(actionKey, authzHandler); } } } } // 注入到ShiroKit类中。ShiroKit类以单例模式运行。 ShiroKit.init(jdbcAuthzService, authzMaps, isAnd); return true; }
/** * 构建actionkey,参考ActionMapping中的实现。 * * @param controllerClass * @param method * @param controllerKey * @return */ private String createActionKey( Class<? extends Controller> controllerClass, Method method, String controllerKey) { String methodName = method.getName(); String actionKey = ""; ActionKey ak = method.getAnnotation(ActionKey.class); if (ak != null) { actionKey = ak.value().trim(); if ("".equals(actionKey)) throw new IllegalArgumentException( controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank."); if (!actionKey.startsWith(SLASH)) actionKey = SLASH + actionKey; } else if (methodName.equals("index")) { actionKey = controllerKey; } else { actionKey = controllerKey.equals(SLASH) ? SLASH + methodName : controllerKey + SLASH + methodName; } return actionKey; }