1. 程式人生 > >基於session做的權限控制

基於session做的權限控制

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 LoginFilter
 
*/ 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; } }
loginFilter 技術分享圖片
   <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做的權限控制