公司的系統比較老了,再加上成本限制,資訊安全方面做的不夠好,選單的權限分配是靠判斷是否在首頁展示給用戶來決定的,如果有人能夠拿到未被展示的選單中執行相關業務邏輯的url(比如修改密碼的url:/user/changePassword),即使沒有權限也能進入,
由于資料庫中只存盤了用戶與角色的關聯、角色與選單項的關聯資訊,并沒有存盤用戶或角色與具體業務邏輯url之間的關聯資訊,因此我想到了利用攔截器來實作鑒權功能,雖然略微有些麻煩,但至少應該比將業務邏輯url也錄入進去再重新給用戶分配權限來的容易,
各位看官如果有什么更好的辦法,歡迎分享!
- 首先是自定義注解:
package cn.bzdj.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
/**
- 自定義注解,用于鑒權
- @author bzdj
- */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthUrl {
//引數填寫父級url,擁有任意父級url的訪問權限,即擁有被注解的controller的訪問權限
String[] urls();
}
- 然后是攔截器:
package cn.bzdj.interceptor;
import java.math.BigDecimal;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import cn.bzdj.annotation.AuthUrl;
/**
* 利用注解AuthUrl來鑒權
* @author bzdj
* */
public class PrevilegeInterceptor extends HandlerInterceptorAdapter {
@Autowired
PrevilegeMapper pm; //這里換成自己鑒權用到的mapper
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String[] urls=null;
if(handler instanceof HandlerMethod) {
HandlerMethod h = (HandlerMethod)handler;
if(h.getMethodAnnotation(AuthUrl.class)==null) //無AuthUrl注解則放行
return true;
urls=h.getMethodAnnotation(AuthUrl.class).urls();
if(urls==null||urls.length==0) //空AuthUrl注解則放行
return true;
//這里填寫自己的判斷當前用戶是否擁有權限的代碼,如果有則return true,
}else{
return true; //放行靜態資源(spring mvc 3.2及以上版本可在xml或配置類中配置)
}
response.sendRedirect(request.getContextPath()+"/index.jsp"); //無權限則重定向到首頁
return false;
}
}
- 之后是配置:
<mvc:interceptors>
<bean class="cn.bzdj.interceptor.PrevilegeInterceptor" />
</mvc:interceptors>
如果spring mvc版本在3.2及以上,可在此處配置放行靜態資源,其他配置差別自行查看相關檔案或百度,
- 最后是使用:
還拿上面修改密碼為例
@PostMapping("/changePassword")
@ResponseBody
@AuthUrl(urls={"/a","/b","/c"}) //引號中填寫需要擁有哪些選單的訪問權限才能使用此url,有多少個就填多少個,不需要鑒權的不加此注解
public Json changePassword(User user){
//相關業務邏輯
}
- 總結:
由于資料庫僅存盤了選單權限,子級url是否有權限只能通過這些選單的url進行判斷,因此想到了攔截器+自定義注解的方法,之所以不用AOP,原因是需要拿到session中存盤的相關資料,用攔截器更加方便,如果各位看官覺得代碼還可以再簡化,或者有更好的解決方案,歡迎留言討論!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/240017.html
標籤:其他
