zoukankan      html  css  js  c++  java
  • 自己动手实现简单权限控制

       最近接手一小型私活,用户量封顶上千,工期预期的也相对宽松,权限控制当然是必不可少。

       web 权限控制,很多项目会引入 shiro/spring-security。

       shiro/spring-security 继承 servlet-->filter抽象接口,运用合适的设计模式,

       通过拦截客户端请求,来实现各个角色对系统资源的访问权限。

       一时兴起,有了自己实现权限控制的想法,遂有此文,如果你用腻了 shiro/spring-security,不妨来和我一起完善它。

       本文只做抛砖引玉之用,重点在思路,具体项目具体编程语言请自行拿捏。

       Git Demo:https://git.oschina.net/LanboEx/simple-auth-demo

       Shiro 中定义拦截过滤链,可以很简单实现上图中的想法,像下面这种姿势(但咱的目的是自己动手)。

      <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            ............
            <!-- 过滤链定义 -->
            <property name="filterChainDefinitions">
                <value>
                    <!--anno:AnonymousFilter 不需要任何权限即可访问-->
                    /login.jsp* = anon
                    /login.do* = anon
                    <!--authc:FormAuthenticationFilter 表单验证权限-->
                    /pages/* = authc
                    /index.jsp* = authc
                    <!--perms:PermissionsAuthorizationFilter 指定授权访问-->
                    /role/edit/* = perms[role:edit]
                    /role/save = perms[role:edit]
                    /role/list = perms[role:view]
                </value>
            </property>
        </bean>

       想法大致和 shiro/spring-security 相同,实现 Filter 接口拦截客户端的对应请求。

       比较有意思的部分,首先你得确定该 Filter 需要拦截什么的请求,服务? 静态页面 ? 交互脚本?网页样式?图片?

       当然项目需要有良好的命名规范,无论是 restful 风格或传统风格。规范项目中的请求 URL 或添加特定的后缀。web.xml 配置比如像下面。

        <filter>
            <filter-name>simpleAuthFilter</filter-name>
            <filter-class>com.rambo.sad.SimpleAuthFilter</filter-class>
            <init-param>
                <param-name>defaultPage</param-name>
                <param-value>/view/login.jsp</param-value>
            </init-param>
            <init-param>
                <param-name>freeServices</param-name>
                <param-value>
                    /view/login.jsp,login.do <!--登录相关-->
                </param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>simpleAuthFilter</filter-name>
            <url-pattern>*.jsp</url-pattern>
        </filter-mapping>
        <filter-mapping>
            <filter-name>simpleAuthFilter</filter-name>
            <url-pattern>*.do</url-pattern>
        </filter-mapping>

       其次你需要确定该本次请求是否有访问该资源的权限,我项目中确定逻辑比较简单,毕竟千人系统。

       将登录页面和登录请求做为 FreeService ,也就是暴露在系统外的资源,登录时在 Session 中放置对应登录对象 PO。

       既方便系统内的相应展示,也可做为用户是否登录的凭证,比如登录服务逻辑像下面。

     @RequestMapping("/login.do")
        public String login(HttpSession httpSession, UserPO userPO) {
            logger.info("login name:" + userPO.getName() + ",pwd:" + userPO.getPasswd());
    
            //一些必要的系统前置工作.....
            httpSession.setAttribute("user", userPO);
            return "success";
        }

       当然也可以引入数据库设计,划分用户角色来制定详细的访问策略。

       最后继承 Filter 接口拦截每次客户端请求,来决定是否能获取到对应的系统资源。

       defaultPage 为权限不足时默认跳转的页面,比如 Filter doFilter方法逻辑像下面。

        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws Exception{
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpSession session = request.getSession(false);
    if ((session == null || session.getAttribute("user") == null) && !isFreeService(request.getRequestURI())) { request.setAttribute("SESSIONFILTER_MSG", "LOGIN_TIMEOUT"); request.getRequestDispatcher(defaultPage).forward(servletRequest, servletResponse);return; } filterChain.doFilter(servletRequest, servletResponse); }

       到此,整个设计思路已叙述清楚,只需自己实现一个 Filter 即可,骚年是不是很简单?

       个人认为其中的可扩展点还很多,做通用并且好用还是有难度的,比如详细的角色访问策略,制定合理的设计模式。

       

  • 相关阅读:
    参数模型和非参数模型
    windows上安装第二个mysql
    Mysql 连接数,最大并发数设置
    mybatis 一次执行多条sql
    微信小程序发布新版本的小程序之后,从发现-小程序中启动,还是看的到旧版本。[转]
    Fragment调用startActivityForResult导致的回调Activity无法获取正确的requestId的问题
    不可重入锁和可重入锁
    Android gradle 各种版本下载
    android 各国语言对应的缩写
    解决乱码setCharacterEncoding("UTF-8")不生效的问题
  • 原文地址:https://www.cnblogs.com/java-class/p/6344191.html
Copyright © 2011-2022 走看看