基於session做的權限控制
阿新 • • 發佈:2018-09-26
msg min 基於 cursor set borde reg 通用 狀態
一直聽說做權限將登陸信息放在session中,實際也說不太出個所以然來,幸運在工作當中接觸到了對應的代碼的copy。
實現思路:
類似於粗粒度的權限控制
將權限控制的文件按包分隔好,對應的url前綴也遵照一些標準統一。
定義包裝用戶信息類,包括登錄後的用戶信息和登錄狀態,用戶授權信息等
使用過濾器,攔截通用請求、登錄請求之外的所有請求。
過濾器中進行session中包裝用戶信息類是否存在,是否登錄,如果有且有效則跳轉對應頁面,無則跳轉登錄頁面
登錄完成在session中寫入用戶的具體信息,包括登錄狀況和授權信息。
權限菜單的控制體現在入口,入口在前端顯示的可操作菜單中只會有用戶被授權的部分。利用z-tree類似組件取得用戶權限和所有菜單的交集。
package com.kunpu.appopiqc.web.filter; import java.io.IOException; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import com.kunpu.appopiqc.web.util.Constant; /** * Servlet Filter implementation class LoginFilterloginFilter*/ public class LoginFilter implements Filter { public FilterConfig config; /** * Default constructor. */ public LoginFilter() { // TODO Auto-generated constructor stub } public static boolean isContains(String container, String[] regx) { boolean result = false; for (int i = 0; i < regx.length; i++) { if (container.indexOf(regx[i]) != -1) { return true; } } return result; } /** * @see Filter#destroy() */ public void destroy() { config = null; } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest hrequest = (HttpServletRequest) request; HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response); String logonStrings = config.getInitParameter("logonStrings"); // 登錄登陸頁面 String includeStrings = config.getInitParameter("includeStrings"); // 過濾資源後綴參數 String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");// 沒有登陸轉向頁面 String disabletestfilter = config.getInitParameter("disabletestfilter");// 過濾器是否有效 if (disabletestfilter.toUpperCase().equals("Y")) { // 過濾無效 chain.doFilter(request, response); return; } String[] logonList = logonStrings.split(";"); String[] includeList = includeStrings.split(";"); // 只對指定過濾參數後綴進行過濾 if (!this.isContains(hrequest.getRequestURI(), includeList)) { chain.doFilter(request, response); return; } // 對登錄頁面不進行過濾 if (this.isContains(hrequest.getRequestURI(), logonList)) { chain.doFilter(request, response); return; } // 判斷用戶是否登錄 String user = (String) hrequest.getSession().getAttribute(Constant.UserOnly); if (user == null) { wrapper.sendRedirect(redirectPath); return; } else { chain.doFilter(request, response); return; } } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig filterConfig) throws ServletException { config = filterConfig; } }
<filter> <filter-name>SessionFilter</filter-name> <filter-class>com.kunpu.appopiqc.web.filter.LoginFilter</filter-class> <!-- 對登錄頁面不進行過濾 --> <init-param> <param-name>logonStrings</param-name> <param-value>/common/;/login/</param-value> </init-param> <!-- 只對指定過濾參數後綴進行過濾 --> <init-param> <param-name>includeStrings</param-name> <param-value>/admin/;/collect/</param-value> </init-param> <!-- 未通過跳轉到登錄界面 --> <init-param> <param-name>redirectPath</param-name> <param-value>/index.jsp</param-value> </init-param> <!-- Y:過濾無效 --> <init-param> <param-name>disabletestfilter</param-name> <param-value>N</param-value> </init-param> </filter> <filter-mapping> <filter-name>SessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <session-config> <session-timeout>60</session-timeout> </session-config>web.xml
@RequestMapping(value = "/common/doLogin", method = RequestMethod.POST, consumes = { "application/json;charset=UTF-8"}) @ResponseBody public AccountLoginResponse doLogin(HttpServletRequest request, HttpServletResponse response, @RequestBody AccountLoginRequest accountRequest) throws Exception { AccountLoginResponse login = new AccountLoginResponse(); // 1.執行登錄操作 try { AccountLoginRequest req = new AccountLoginRequest(); req.setSysId(APPCodeEnum.KPBP_APPOPIQC.sysId); req.setReqSerial(UUID.randomUUID().toString()); req.setInstitutionCode(accountRequest.getInstitutionCode()); req.setAccountCode(accountRequest.getAccountCode()); req.setAccountPassword(accountRequest.getAccountPassword()); login = accountFacade.login(req); LOGGER.error("登錄結果{}", ToStringBuilder.reflectionToString(login), ToStringStyle.SHORT_PREFIX_STYLE); if (login != null && AppopiqcRespCode.RESP_000000.getCode().equals(login.getRespCode())) { request.getSession().setAttribute(Constant.LoginUser, login); request.getSession().setAttribute(Constant.UserOnly, "true"); return login; } } catch (Exception e) { LOGGER.error("", e); } // 2.顯示錯誤信息 login = new AccountLoginResponse(); login.setMemo("賬號/密碼錯誤"); request.getSession().setAttribute(Constant.LoginUser, null); request.getSession().setAttribute(Constant.UserOnly, null); return login; }登錄代碼
@RequestMapping(value = "/admin/center") public ModelAndView center(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView(); AccountLoginResponse accountLoginResponse = null; try { accountLoginResponse = (AccountLoginResponse) request.getSession().getAttribute(Constant.LoginUser); } catch (Exception e) { request.setAttribute("retCode", CommonEnums.NOT_SESSION.getCode()); } QueryMenuRequest req = new QueryMenuRequest(); req.setSysId(APPCodeEnum.KPBP_APPOPIQC.sysId); req.setReqSerial(UUID.randomUUID().toString()); QueryMenuResponse resp = menuFacade.queryMenuList(req); LOGGER.debug("用戶菜單{}", ToStringBuilder.reflectionToString(resp), ToStringStyle.SHORT_PREFIX_STYLE); List<MenuBean> menus = resp == null ? new ArrayList() : resp.getMenuBeanList(); String isLeader = accountLoginResponse.getIsLeader(); if (menus != null && !menus.isEmpty()) { for (int i = 0; i < menus.size(); i++) { // 針對菜單特殊處理,暫時沒有 } } mv.addObject("menus", menus); mv.setViewName("center"); return mv; }菜單展示代碼
<!--正常菜單--> <div class="theme-left-normal"> <!--theme-left-switch 如果不需要縮進按鈕,刪除該對象即可--> <div class="left-control-switch theme-left-switch"><i class="fa fa-chevron-left fa-lg"></i></div> <!--start class="easyui-layout"--> <div class="easyui-layout" data-options="border:false,fit:true"> <!--start region:‘north‘--> <div data-options="region:‘north‘,border:false" style="height:100px;"> <!--start theme-left-user-panel--> <div class="theme-left-user-panel"> </div> <!--end theme-left-user-panel--> </div> <!--end region:‘north‘--> <!--start region:‘center‘--> <div data-options="region:‘center‘,border:false"> <!--start easyui-accordion--> <div class="easyui-accordion" data-options="border:false,fit:true"> <#if menus?? > <#list menus as menu> <#if (menu.menuType!‘‘) == ‘DESKTOP_MENU‘ && (menu.parentCode!‘‘) == ‘‘> <div title="${menu.menuName!}"> <ul class="easyui-datalist" data-options="border:false,fit:true"> <#list menus as menu2> <#if menu2.parentCode! == menu.menuCode> <li> <a onclick="openHref(‘${menu2.menuCode}‘,‘${menu2.menuName!}‘,‘${menu2.menuUrl!}‘)" target="mainFrame" style="cursor:pointer;">${menu2.menuName!}</a></li> </#if> </#list> </ul> </div> </#if> </#list> </#if> </div> <!--end easyui-accordion--> </div> <!--end region:‘center‘--> </div> <!--end class="easyui-layout"--> </div> <!--最小化菜單--> <div class="theme-left-minimal"> <ul class="easyui-datalist" data-options="border:false,fit:true"> <#if menus??> <#list menus as menu> <#if (menu.menuType!‘‘) == ‘DESKTOP_MENU‘ && (menu.parentCode!‘‘) == ‘‘> <#list menus as menu2> <#if menu2.parentCode! == menu.menuCode > <li> <a onclick="openHref(‘${menu2.menuCode}‘,‘${menu2.menuName!}‘,‘${menu2.menuUrl!}‘)" style="cursor:pointer;"><i class="fa fa-home fa-2x"></i> <p>${menu2.menuName!}</p></a></li> <#break> </#if> </#list> </#if> </#list> </#if> <li><a class="left-control-switch"><i class="fa fa-chevron-right fa-2x"></i> <p>打開</p></a></li> </ul> </div>菜單代碼的頁面
@RequestMapping(value = "/account/toLogout") public ModelAndView toLogout(HttpServletRequest request) throws Exception { ModelAndView mv = new ModelAndView(); mv.setViewName("account/login"); request.getSession().setAttribute(Constant.LoginUser, null); request.getSession().setAttribute(Constant.UserOnly, null); return mv; } @RequestMapping(value = "/account/doModifyPasswd", method = RequestMethod.POST) @ResponseBody public Result<Void> doModifyPasswd(HttpServletRequest request, @RequestParam("oldPasswd") String oldPasswd, @RequestParam("newPasswd") String newPasswd, @RequestParam("repleatPasswd") String repleatPasswd) throws Exception { String msg = ""; String errorCode = "-1"; Result<Void> rs = new Result<Void>(); rs.setCode(errorCode); AccountLoginRequest loginReq = new AccountLoginRequest(); AccountLoginResponse login = (AccountLoginResponse) request.getSession().getAttribute(Constant.LoginUser); if (login == null) { msg = "用戶還未登錄."; rs.setCode(errorCode); rs.setMsg(msg); return rs; } loginReq.setInstitutionCode(login.getInstitutionCode()); loginReq.setAccountCode(login.getAccountCode()); loginReq.setAccountPassword(oldPasswd); loginReq.setSysId(APPCodeEnum.KPBP_APPOPIQC.sysId); loginReq.setReqSerial(UUID.randomUUID().toString()); // 校驗原密碼 AccountLoginResponse checkOldPwd = accountFacade.login(loginReq); if (StringUtils.isNotEmpty(checkOldPwd.getRespCode()) && !checkOldPwd.getRespCode().equals(AppopiqcRespCode.RESP_000000.getCode())) { msg = "舊密碼不正確."; rs.setCode(errorCode); rs.setMsg(msg); return rs; } if (StringUtils.isNotBlank(newPasswd) && !newPasswd.equals(repleatPasswd)) { msg = "兩次輸入的密碼不一致."; rs.setCode(errorCode); rs.setMsg(msg); return rs; } AccountChangePasswordRequest changePasswordReq = new AccountChangePasswordRequest(); changePasswordReq.setInstitutionCode(login.getInstitutionCode()); changePasswordReq.setAccountCode(login.getAccountCode()); // 修改用戶密碼 changePasswordReq.setAccountPassword(newPasswd); changePasswordReq.setSysId(APPCodeEnum.KPBP_APPOPIQC.sysId); changePasswordReq.setReqSerial(UUID.randomUUID().toString()); try { AccountChangePasswordResponse account = accountFacade.changePassword(changePasswordReq); LOGGER.debug("修改結果{}", ToStringBuilder.reflectionToString(account), ToStringStyle.SHORT_PREFIX_STYLE); if (account != null && AppopiqcRespCode.RESP_000000.getCode().equals(account.getRespCode())) { rs.setCode("1"); rs.setMsg("修改用戶密碼成功"); return rs; } errorCode = (account == null) ? "-1" : account.getRespCode(); } catch (Exception e) { LOGGER.error("", e); } rs.setCode(errorCode); rs.setMsg("修改用戶密碼失敗"); return rs; } @RequestMapping(value = "/account/toModifyPassword") public ModelAndView toModifyPasswd(HttpServletRequest request) { ModelAndView mv = new ModelAndView(); mv.setViewName("/account/password"); request.getSession().setAttribute(Constant.UserOnly, null); return mv; } @RequestMapping(value = "/account/info") @ResponseBody public AccountLoginResponse userInfo(HttpServletRequest request) { AccountLoginResponse login = (AccountLoginResponse) request.getSession().getAttribute(Constant.LoginUser); return login; }註銷改密查用戶信息等
例子鏈接:https://pan.baidu.com/s/1BvLleNnIyvoy-AeRobZM-g
基於session做的權限控制