很多系统都会有多重系统角色,并且每个角色的权限都是不一样的,进行权限管理是一件非常复杂的事情,我这里只是对方法进行权限管理,将权限跟API一一对应起来,如果对这和API没有权限,就无法使用该API,当然这种方法级别的权限管理,范围还是太大,有待进一步细化。
具体的原理就是:使用权限码,假设我的使用的是128位的权限码,那都能设置128种方法的权限,如果需要更多,可以继续加。每一个API方法都对应唯一一个权限码,即当前位是1其余位都是0;每一个用户拥有一个128为的权限集,如果当前位对应1的话,就说明该用户可以操作这个API,否则就是无权限。
用户权限集
每个用户都拥有一个128位权限集,用两个long类型实现。
User.java
@JsonIgnoreProperties(value = {"permissionCodeHigh", "permissionCodeLow"})
public class User implements java.io.Serializable {
private static final long serialVersionUID = -5559386013177436565L;
private String id;
private String name;
private String email;
private String address;
private String permissionCode; //权限代码 length = 128
// 省略getter和setter。。。。
private Long permissionCodeHigh;
private Long permissionCodeLow;
/**
* 获取访问权限码高64位
* @date 2015-1-4
* @return
*/
public long getPermissionCodeHigh() {
if (this.permissionCodeHigh == null) {
synchronized(this) {
if (this.permissionCode != null&& this.permissionCode.matches("^[0-1]{128}$")) {
permissionCodeHigh = Long.parseLong(this.permissionCode.substring(0, 64), 2);
} else {
permissionCodeHigh = new Long(0);
}
}
}
return this.permissionCodeHigh.longValue();
}
/**
* 获取访问权限码低64位
* @date 2015-1-4
* @return
*/
public long getPermissionCodeLow() {
if (this.permissionCodeLow == null) {
synchronized(this) {
if (this.permissionCode != null&& this.permissionCode.matches("^[0-1]{128}$")) {
permissionCodeLow = Long.parseLong(this.permissionCode.substring(64), 2);
} else {
permissionCodeLow = new Long(0);
}
}
}
return this.permissionCodeLow.longValue();
}
API权限码
API方法的权限码是用注解定义的。首先定义一个权限码的注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredPermission {
long high() default 0;
long low() default 0;
}
使用注解定义权限码
@RequiredPermission(hight = 0,low = 1)
@RequestMapping(value = "/api/{sessionid}/tables", method = RequestMethod.GET)
public @ResponseBody
ResultInfo<List<InnerControlTable>> get(@PathVariable("sessionid") String sessionID)
此方法对应的128为权限码就是 000000….0000(127个0)1,每一个方法只能允许一位是1,其余位都必须为0,这样128为的权限码可以为128个方法定义权限。
拦截器处理
获取当前用户的权限集,再获取访问方法的权限码,如果两者相与结果为0,说明待访问的方法的权限码不在用户的权限集里,因此没有权限访问。
public class AuthorityInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String url = request.getServletPath();
RequiredPermission annotation ;
try{
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
annotation = method.getAnnotation(RequiredPermission.class);
}catch(ClassCastException e){
return true;
}
if (annotation != null) {
//与用户权限代码比较,有一个如果不为0,则说明有相应的权限。
if ((annotation.low() & currUser.getPermissionCodeLow()) == 0 &&
(annotation.high() & currUser.getPermissionCodeHigh()) == 0) {
//没有权限,返回错误。
PrintWriter out = response.getWriter();
out.print(JsonBinder.getInstance().toJson(ResultInfo.getIllegalPermission()));
out.flush();
out.close();
return false;
}
}
}
return true;
}
}