1.前言
在为web应用实现权限管理时通常需要我们手动为每个路径添加对应的权限,名称以及相关信息,以便于实现统一管理,但手动录入未免太过繁琐,这里借助注解的方式实现类似swagger的功能,能在开发时直接为路径添加信息,实现统一管理。
路径 | 名称 | 权限点 | 备注 |
/home/page/index.sdo | 首页 | P_HOME | 首页页面 |
2.环境
整个web环境是基于springboot+maven搭建的,众所周知,springboot只是spring的一个简化配置的版本,所以这种方法在普通spring项目中同样适用
3.实现
1.定义注解
/**
* 用于注解需要进行权限控制的类
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface URLControl {
}
/**
* 注解方法,生成权限信息
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface URLMessage {
String permissionName();
String url();
String description() default "";
String parent() default "";
}
以上两个注解,前一个用于标注需要进行路径管理的控制器类,后一个用于标注控制器内部的指定接口,需要在注解中提供接口的信 息,这里只包含了,权限名,路径, 描述和父路径这四个信息,有其他需要的可以自己扩展
2.运行时获取所有注解信息
package com.fastweb.fundation.message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component("urlMessageCenter")
public class URLMessageCenter {
private static List<Map<String,String>> urls;
@Autowired
ApplicationContext applicationContext;
public void loadURL(){
urls = new ArrayList<>();
Map o = applicationContext.getBeansWithAnnotation(URLControl.class);
for(Object key:o.keySet()){
Method[] methods = o.get(key).getClass().getMethods();
for(int i = 0;i < methods.length;i++){
URLMessage message = methods[i].getAnnotation(URLMessage.class);
if(message != null){
Map url = new HashMap();
url.put("description",message.description());
url.put("parent",message.parent());
url.put("permissionName",message.permissionName());
url.put("url",message.url());
urls.add(url);
}
}
}
}
public List<Map<String,String>> getURL(){
if(urls == null){
synchronized (URLMessageCenter.class){
if(urls == null){
loadURL();
}
}
}
return urls;
}
}
借助URLMessageCenter可以在任何时刻获取当前所有被注解的路径信息,对路径信息进行操作,例如,在项目启动时对路径信息进 行操作
package com.fastweb.fundation.start;
import com.fastweb.fundation.message.URLMessageCenter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class PermissionRunner implements ApplicationRunner {
@Autowired
URLMessageCenter urlMessageCenter;
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
List<Map<String,String>> urls = urlMessageCenter.getURL();
/**
* 对路径进行统一操作
*/
}
}
4.测试
package com.fastweb.mod.admin.home;
import com.fastweb.Authorization.mod.UserDetail;
import com.fastweb.fundation.action.BaseAction;
import com.fastweb.fundation.message.URLControl;
import com.fastweb.fundation.message.URLMessage;
import com.fastweb.fundation.message.URLMessageCenter;
import com.fastweb.fundation.mod.menu.Menu;
import com.fastweb.fundation.mod.menu.MenuService;
import com.fastweb.fundation.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Controller("adminHome")
@RequestMapping("admin/home")
@URLControl
public class HomeAction extends BaseAction {
@Autowired
private MenuService menuService;
@Override
protected void setService(BaseService service) {
this.service = service;
}
@Override
protected String getPrefix() {
return "admin/home/";
}
@URLMessage(permissionName = "P_ADMIN_INDEX",url = "/admin/home/page/index",description = "PAGE-后台外层页面",parent = "")
public String index(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws SQLException, IllegalAccessException {
List<Menu> menus = this.menuService.getMenus();
UserDetail user = (UserDetail) SecurityContextHolder.getContext()
.getAuthentication()
.getPrincipal();
modelMap.put("menus",menus);
modelMap.put("user",user);
return "index";
}
@URLMessage(permissionName = "P_ADMIN_MAIN",url = "/admin/home/page/main",description = "PAGE-后台首页",parent = "")
public String main(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap){
return "main";
}
}
实测成功,获取到了路径信息,其他代码就不写了