網站開發,就會涉及到人員登錄,人員呢就會有權限。今天就理一下Springmvc的權限實現過程。
1.首先要知道@AuthPassport這個注解。這個注解能就是實現權限驗證的注解。
2.在需要驗證權限的Controller的方法上添加注解
@AuthPassport//權限驗證
@AuthPassport(validate=false)//validate默認為true,表示需要驗證,當validate 為false時表示不需要驗證
@AuthPassport(authority="common")//只有有common權限的才可以調用方法
@AuthPassport(authority = Const.AUTH_LOG)//只有有Const.AUTH_LOG常量權限的才可以調用方法
以上是我的項目中常用的權限注解方式。
3.配置項目的springservlet-config.xml或者springmvc.xml中添加如下內容:
這樣在執行每個action方法是都會調用AuthInterceptor處理,當判斷action上有我們定義AuthPassport注解時就會執行里面的權限驗證邏輯。
<mvc:interceptors>
<!-- 國際化操作攔截器 如果采用基於(請求/Session/Cookie)則必需配置 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
<!-- 如果不定義 mvc:mapping path 將攔截所有的URL請求 -->
<bean class="com.tj720.mip.framework.auth.AuthInterceptor"></bean>
</mvc:interceptors>
其中第一個bean是spring-webmvc的jar包中的
另外一個bean就是自己寫的權限實現文件
package com.tj720.mip.framework.auth; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Inherited @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AuthPassport { boolean validate() default true; String authority() default ""; }
package com.tj720.mip.framework.auth; import java.net.InetAddress; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.tj720.mip.framework.MyException; import com.tj720.mip.inter.dao.ICacheDao; import com.tj720.mip.springbeans.Config; import com.tj720.mip.springbeans.GetBeanByConfig; import com.tj720.mip.utils.Aes; import com.tj720.mip.utils.Const; import com.tj720.mip.utils.MyCookie; import com.tj720.mip.utils.MyString; import com.tj720.mip.utils.Tools; /** * 對登錄狀態進行攔截 * @author * */ public class AuthInterceptor extends HandlerInterceptorAdapter { @Autowired private GetBeanByConfig getBEanByConfig; @Autowired private Config config; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(handler.getClass().isAssignableFrom(HandlerMethod.class)){ AuthPassport authPassport = ((HandlerMethod) handler).getMethodAnnotation(AuthPassport.class); // 未登陸用戶唯一識別 String uuid = MyCookie.getCookie(Const.COOKIE_UUID, false, request); if( MyString.isEmpty(uuid) ){ MyCookie.addCookie(Const.COOKIE_UUID, System.currentTimeMillis() + Tools.getChar(10), response); } try{ // 返回服務器ip response.setHeader("serviceIp", InetAddress.getLocalHost().getHostAddress()); }catch(Exception e){ e.printStackTrace(); response.setHeader("serviceIp", "服務器配置異常,無法獲取服務器IP"); } if(authPassport == null || authPassport.validate() == false) return true; String token = MyCookie.getCookie(Const.COOKIE_TOKEN, false, request); String uid = MyCookie.getCookie(Const.COOKIE_USERID, false, request); // 前端沒有傳遞token,未登錄 if(MyString.isEmpty(token) || MyString.isEmpty(uid) || !Aes.desEncrypt(token).equals(uid)){ if(request.getRequestURI().endsWith("admin.do")) response.sendRedirect("loginOrRegister.do#/login"); else{ String acceptHeader = request.getHeader("Accept"); String ajaxParam = request.getParameter("text/html;type=ajax"); if ("text/html;type=ajax".equals(acceptHeader) || StringUtils.hasText(ajaxParam)) { throw new MyException("000021"); } else { response.sendRedirect(request.getContextPath()+"/toLogin.do"); } } } // 后端沒登錄信息:登錄超時 ICacheDao cacheDao = getBEanByConfig.getCacheDao(); Object obj = cacheDao.getObj(Const.CACHE_USER + uid); if(obj == null){ // 刪除cookie MyCookie.deleteCookie(Const.COOKIE_TOKEN, request, response); if(request.getRequestURI().endsWith("admin.do")){ response.sendRedirect("loginOrRegister.do#/login"); return false; } else{ String acceptHeader = request.getHeader("Accept"); String ajaxParam = request.getParameter("text/html;type=ajax"); if ("text/html;type=ajax".equals(acceptHeader) || StringUtils.hasText(ajaxParam)) { throw new MyException("000021"); } else { response.sendRedirect(request.getContextPath()+"/toLogin.do"); return false; } } } // 每次訪問,將用戶登錄有效信息延長 cacheDao.setObj(Const.CACHE_USER + uid, obj, config.getLoginInforTime()); if(!authPassport.authority().equals("")){ return Tools.hasAuth(authPassport.authority()); }else{ return true; } } else return true; } }
4.在LoginController中
5.在LoginInfoDto中要放登陸者用到的所有信息字段
6.查出用戶的所有權限,用,分割
7.在需要的權限的方法前邊加注解
8.在jsp頁面判斷等級為3的顯示if標簽中的內容
9.判斷有edit權限的可以看到if標簽下的內容
10.當然,在jsp頁面要加標簽
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
11總結思路:
首先配置spring權限驗證的配置文件,
在登錄按鈕中加方法去login方法中驗證用戶名密碼是否正確,
如果正確將user對象放到session和cookie中。
這樣在執行每個action方法是都會看有沒有@AuthPassport注解,
如果有就調用AuthInterceptor處理,執行權限驗證邏輯。
其中涉及的表是user表和auth表