一種基于注解的Spring MVC權限控制方法
簡介
本文介紹一種采用annotation來對spring-mvc進行權限控制的方法. 通過枚舉類來定義權限項. 將annotation標注到需要控制權限的spring-mvc方法上. 然后,在spring-mvc中定義全局過濾器, 過濾所有spring-mvc方法, 查看方法上的權限annotation信息, 以此對權限進行控制.
優點
編寫比較方便, 在需要控制權限的方法上進行annotation的標注即可, ide能夠對annotation進行識別支持. 查看權限配置比較方便, 因為annotation就在方法上, 不用去其他地方翻看. 實現方式比較簡單.
具體實現
1.建立權限枚舉類
建立權限枚舉類型, 用于描述權限的種類, 包含了權限的名稱. 每個枚舉值中包含了權限中文名稱和權限索引值(即權限位). (思考:是否可以直接用中文名稱作為枚舉值的名稱,我在其他程序已經用了中文枚舉名稱了,暫時沒有遇到問題)
public enum AuthorityType{
// 包含了枚舉的中文名稱, 枚舉的索引值
WORKER("增刪改查員工", 1),
SALES_ORDER_CREATE("創建訂單", 6),
SALES_ORDER_FIND("查看訂單", 7),
SALES_ORDER_MODIFY("修改訂單", 8),
SALES_ORDER_DELETE("刪除訂單", 9),
;
private String name;
private int index;
private AuthorityType(String name, int index) {
this.name = name;
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
} 2.登錄方式的枚舉類
登錄方式的枚舉類, page代表傳統登錄頁面, json表示ajax的登錄
public enum ResultTypeEnum {
//整頁刷新
page,
//json數據
json
} 3.建立表示權限annotation類
建立annotation類, 用于標注到需要權限驗證的地方
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FireAuthority {
AuthorityType[] authorityTypes();
ResultTypeEnum resultType() default ResultTypeEnum.page;
} 4.在user類中加入權限字段
在user用戶類中添加文本字段表示權限, 字段長度為250字符(因為mysql默認255個字符,可以代表250個權限應該夠用了), 字符內容是0或者1. 1表示有權限, 0表示無權限. 提示: 對于用戶的權限配置, 只要將對應的權限位設置為0或者1即可.
create table user (
id integer not null auto_increment,
name varchar(255),
right_content varchar(255),
primary key (id)
) type=InnoDB 5.權限驗證算法
權限判斷方法, 權限判斷的實現算法, 用于判斷是否有權限
public class AuthorityHelper {
/**
* 判斷是否有權限
* @param akey aString中位置的索引值,也就是權限位
* @param aString 權限字段,比如 11010101011101
* @return
*/
public static boolean hasAuthority(int akey,String aString){
return ConstanHelper.getAuthorityVaule(akey,rc);
if(aString==null || "".equals(aString)){
return false;
}
char value = aString.charAt(akey);
if(value == '1'){
return true;
}
return false;
}
} 6.建立控制權限的interceptor類
建立interceptor類, 用于過濾需要控制權限的方法.
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class AuthorityAnnotationInterceptor extends HandlerInterceptorAdapter {
final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.debug("");
HandlerMethod handler2=(HandlerMethod) handler;
FireAuthority fireAuthority = handler2.getMethodAnnotation(FireAuthority.class);
if(null == fireAuthority){
//沒有聲明權限,放行
return true;
}
logger.debug("fireAuthority", fireAuthority.toString());
HttpSession session = request.getSession();
Worker manager = (Worker)session.getAttribute(SessionHelper.WorkerHandler);
boolean aflag = false;
for(AuthorityType at:fireAuthority.authorityTypes()){
if(AuthorityHelper.hasAuthority(at.getIndex(), manager.getRightContent())==true){
aflag = true;
break;
}
}
if(false == aflag){
if (fireAuthority.resultType() == ResultTypeEnum.page) {
//傳統的登錄頁面
StringBuilder sb = new StringBuilder();
sb.append(request.getContextPath());
sb.append("/oprst.jsp?oprst=false&opmsg=").append(URLEncoder.encode(ControllerProperty.NOT_HAVE_AUTHORITY,"utf-8"));
response.sendRedirect(sb.toString());
} else if (fireAuthority.resultType() == ResultTypeEnum.json) {
//ajax類型的登錄提示
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
OutputStream out = response.getOutputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,"utf-8"));
pw.println("{\"result\":false,\"code\":12,\"errorMessage\":\""+ControllerProperty.NOT_HAVE_AUTHORITY+"\"}");
pw.flush();
pw.close();
}
return false;
}
return true;
}
} 7.配置interceptor類
在spring-mvc中配置interceptor, 實現過濾.
<mvc:interceptors>
<bean class="interceptor.AuthorityAnnotationInterceptor"></bean>
</mvc:interceptors> 8.標注需要控制權限的方法
在需要控制訪問的spring-mvc方法上面加上對應的標注.
//方式一
@FireAuthority(AuthorityType. SALES_ORDER_CREATE)
@RequestMapping(value="/save.spr", method=RequestMethod.POST)
public ModelAndView save(String name) throws Exception {
//some code
} //方式二
@FireAuthority(authorityTypes = {AuthorityType.SALES_ORDER_DELETE,AuthorityType.SALES_ORDER_CREATE})
@RequestMapping(value="/save.spr", method=RequestMethod.POST)
public ModelAndView save(String name) throws Exception {
//some code
} //方式三
@FireAuthority(authorityTypes = AuthorityType.SALES_ORDER_DELETE, resultType=ResultTypeEnum.page)
@RequestMapping(value="/save.spr", method=RequestMethod.POST)
public ModelAndView save(String name) throws Exception {
//some code
} 9.完成了
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!