基于session做的权限控制

一直听说做权限将登陆信息放在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

原文地址:https://www.cnblogs.com/aigeileshei/p/9707055.html

时间: 2024-10-13 15:20:02

基于session做的权限控制的相关文章

使用nginx和iptables做访问权限控制(IP和MAC)

之前配置的服务器,相当于对整个内网都是公开的 而且,除了可以通过80端口的nginx来间接访问各项服务,也可以绕过nginx,直接ip地址加端口访问对应服务 这是不对的啊,所以我们要做一些限制 因为只是对特定的人提供服务,而且局域网IP和MAC都是固定的,所以可以直接用白名单,其他的全部拒绝 /**************************************使用nginx做访问权限控制*********************************/ 先在nginx做设置 在/et

通过注解@做细粒度权限控制

先定义一个注解 import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface AnnotationLimit { String mid(); String pid(); } public static void main(String[] args) throws NoSuchMeth

基于thinkphp的RBAC权限控制

RBAC  Role-Based Access Control 权限控制在后台管理中是十分常见的,它的模型大体上是下面这张图的形式 我用的字段和上面不一样,图只是个示例 一个简易的权限控制模型只需要3个表就行了 user表:记录用户的信息和用户的角色 ->user_id:用户的id ->user_role_id:用户的角色信息  0,1,2分别为超级管理员,经理,员工 ->其它省略... role表:记录不同的角色信息,和他们拥有的权限 ->role_id:角色的id    1为经

spring boot系列03--spring security (基于数据库)登录和权限控制(下)

(接上篇) 后台 先说一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig 1 @Configuration 2 @EnableWebSecurity 3 public class AuthConfig extends WebSecurityConfigurerAdapter { 4 @Override 5 protected void configure(HttpSecurity httpSecurity) throws Exception

spring boot系列--spring security (基于数据库)登录和权限控制

先说一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig 1 @Configuration 2 @EnableWebSecurity 3 public class AuthConfig extends WebSecurityConfigurerAdapter { 4 @Override 5 protected void configure(HttpSecurity httpSecurity) throws Exception { 6 http

基于url拦截实现权限控制

用户表,角色表,用户角色表,权限表,权限角色表 1.用户通过认证(可以是验证用户名,密码等) 2.登陆拦截器,为公开的url放行, 登陆时,将用户信息放入session中,获得用户的权限集合,将集合放到session中,将用户的看查看的菜单权限放到session,用于显示导航菜单 3.权限拦截器,系统内访问时,可以通过拦截器判断权限集合中有没有此url,如果有,允许操作.没有无权访问

2.4.4.3、Django用user表last_name字段做权限控制

这不是最好的方法! 数据库User表中因为是系统初始化的表,如果添加额外的字段需要修改django源文件,不利于移植,为避免带来其他问题,可以使用last_name字段做为权限控制,当然也可以用profile方法为user表添加新字段(对于user表示一对一关系,但不是在User表中),session在用户登录之后会一直存储user的信息,所以用user表中的字段在html中引用实现更简单一点(group可以在视图里使用) 如下图: 在http://10.1.1.145:8000/admin/a

Spring Security(17)——基于方法的权限控制

目录 1.1     intercept-methods定义方法权限控制 1.2     使用pointcut定义方法权限控制 1.3     使用注解定义方法权限控制 1.3.1    JSR-250注解 1.3.2    @Secured注解 1.3.3    支持表达式的注解 1.4     方法权限控制的拦截器 1.4.1    MethodSecurityInterceptor 1.4.2    AspectJMethodSecurityInterceptor 之前介绍的都是基于URL

aProxy: 带认证授权和权限控制的反向代理

前段时间很多数据库因为没有做好权限控制暴露在外网被删然后遭勒索的事件,而类似的有些内网的web服务也会被开放到公网并且没有做任何权限控制的,这样也会有一定的风险.所以就决定写篇文章简单介绍一个小工具. aProxy是做什么用的 例如我们有很多服务,例如Hadoop.Aerospke.Riak等,都会有一些监控的web界面,我们需要查看这些线上服务的情况,但是又不能完全将这些服务开放到外网,让别人看到,这时候我们可能的做法是通过拨VPN,或者是通过Nginx的BaseAuth验证,又或者是简单的本