ShiroInitPlugin.java 4.9 KB
package com.framework.shiro;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 跟据DB设置 初始化权限设置
 * 
 * @author dingoolu
 *
 */
public class ShiroInitPlugin implements ApplicationListener<ContextRefreshedEvent> {
	@Autowired
	private ShiroFilterFactoryBean shiroBean;

	public void onApplicationEvent(ContextRefreshedEvent event) {
		if (event.getApplicationContext().getParent() == null) {
			Map<String, String> authMap = new HashMap<String, String>();
			authMap.put("/login", "anon");
			authMap.put("/authImage**", "anon");
			List<MenuUrl> urls = getAllAuthUrl(event.getApplicationContext());
			for (MenuUrl mu : urls) {
				authMap.put(mu.getMenuUrl(), "perms[" + mu.getMenuId().toString() + "]");  // 添加权限
			}
			shiroBean.setFilterChainDefinitionMap(authMap);
		}
	}

	/**
	 * 获取项目中所有需要权限控制的url路径 需要权限控制的类必须添加注解Menu,其中menu注解的值对应权限设定中对应的menuId
	 * 
	 * @param context
	 * @return
	 */
	private List<MenuUrl> getAllAuthUrl(ApplicationContext context) {
		List<MenuUrl> result = new ArrayList<MenuUrl>();
		Map<String, Object> beans = context.getBeansWithAnnotation(Menu.class);
		for (Object obj : beans.values()) {
			Class clazz = getSrcClass(obj);
			Menu m = (Menu) clazz.getAnnotation(Menu.class);
			RequestMapping classUrl = null;
			if (clazz.isAnnotationPresent(RequestMapping.class)) {
				classUrl = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
			}
			List<PermRequestMapping> urlMapList = getObjectUrlMethods(obj);
			String tmpUrl = null;
			for (PermRequestMapping urlMap : urlMapList) {
				String[] urls = urlMap.getMapping().value();
				for (String url : urls) {
					MenuUrl mu = new MenuUrl();
					mu.setMenuId(m.value());
					tmpUrl = url;
					if (classUrl != null) {
						tmpUrl = classUrl.value()[0] + url;
					}
					mu.setMenuUrl(getCompareUrl(tmpUrl));
					result.add(mu);
				}
			}
		}
		return result;
	}

	public static void main(String[] args) {
		// SystemConfigLoader.loadSystemConfig();
		// new ShiroInitPlugin().getAllAuthUrl(SystemConfigLoader.context);
	}

	/**
	 * 将url如/user/readUser/{userId}替换成/user/readUser/**
	 * 
	 * @param url
	 * @return
	 */
	private String getCompareUrl(String url) {
		if (url.indexOf("{") > -1 && url.indexOf("}") > -1) {
			url = url.substring(0, url.indexOf("{")) + "**" + url.substring(url.indexOf("}") + 1);
			return getCompareUrl(url);
		} else {
			return url;
		}
	}

	/**
	 * 获取类所有方法中的@RequestMapping注解信息
	 * 
	 * @param obj
	 * @return
	 */
	private List<PermRequestMapping> getObjectUrlMethods(Object obj) {
		List<PermRequestMapping> result = new ArrayList<PermRequestMapping>();
		Class clazz = obj.getClass();
		// if(AopUtils.isJdkDynamicProxy(obj)){
		// InvocationHandler invo = Proxy.getInvocationHandler(obj);
		// AdvisedSupport advised = (AdvisedSupport) new DirectFieldAccessor(
		// obj).getPropertyValue("advised");
		// clazz = advised.getTargetClass();
		// }else{
		// clazz = AopUtils.getTargetClass(obj);
		// }
		clazz = getSrcClass(obj);
		Method[] mtds = clazz.getMethods();
		for (Method m : mtds) {
			if (m.isAnnotationPresent(RequestMapping.class)) {
				PermRequestMapping prm = new PermRequestMapping();
				prm.setMapping(m.getAnnotation(RequestMapping.class));
				result.add(prm);
			}
		}
		return result;
	}

	public Class getSrcClass(Object obj) {
		Class clazz = obj.getClass();
		String classStr = clazz.toString();
		if (clazz.toString().indexOf("$$") > -1) {
			classStr = clazz.toString().substring(clazz.toString().indexOf(" ") + 1, clazz.toString().indexOf("$$"));
		} else {
			return clazz;
		}
		try {
			return Class.forName(classStr);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		// if(AopUtils.isJdkDynamicProxy(obj)){
		// InvocationHandler invo = Proxy.getInvocationHandler(obj);
		// AdvisedSupport advised = (AdvisedSupport) new DirectFieldAccessor(
		// obj).getPropertyValue("advised");
		// clazz = advised.getTargetClass();
		// }else{
		// clazz = AopUtils.getTargetClass(obj);
		//
		// }
		// return clazz;
	}

	class PermRequestMapping {
		private RequestMapping mapping;

		public RequestMapping getMapping() {
			return mapping;
		}

		public void setMapping(RequestMapping mapping) {
			this.mapping = mapping;
		}

	}
}