• BOS10——权限控制的实现,apache shiro权限管理框架的使用,参数同名问题,EasyUI的combotree的使用


    1、权限控制的实现

    2、两种实现权限管理的方法

    1)底层基于拦截器或者过滤器实现

    2)底层基于代理技术实现,为Action创建代理对象,由代理对象进行权限校验(实际上Transtion事务注解也是将Service变成动态代理对象)

    3、apache shiro框架的使用

    shiro框架的核心功能:

    • 认证
    • 授权
    • 会话管理
    • 加密

    shiro框架认证流程:

    • Application Code:应用程序代码,由开发人员负责开发的
    • Subject:框架提供的接口,代表当前用户对象
    • SecurityManager:框架提供的接口,代表安全管理器对象
    • Realm:可以开发人员编写,框架也提供一些,类似于Dao,用于访问权限数据

    在项目中应用shiro框架进行认证:

    一、在realm中进行认证(login)

    第一步:引入shiro框架相关的jar 

    第二步:在web.xml中配置spring框架提供的用于整合shiro框架的过滤器(一定要在Struts的过滤器前)

    <!--过滤器,整合shiro-->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    启动tomcat服务器,抛出异常:spring工厂中不存在一个名称为“shiroFilter”bean对象

    第三步:在spring配置文件中配置beanidshiroFilter

    第四步:配置安全管理器

    <!-- *************************配置shiro框架的过滤工厂************************* -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/login.jsp"/>
        <property name="successUrl" value="/index.jsp"/>
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
    
        <!--设定URL级别拦截策略-->
        <property name="filterChainDefinitions">
            <value>
                /css/** = anon
                /js/** = anon
                /images/** = anon
                /validatecode.jsp* = anon
                /login.jsp = anon
                /userAction_login.action = anon
                /page_base_staff.action = perms["staff-list"]
                /* = authc
            </value>
        </property>
    </bean>
    
    <!--配置安全管理器-->
    <bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"/>
    </bean>
    

    第五步:修改UserAction中的login方法,使用shiro提供的方式进行认证操作

    /**
     * 用户登录,使用shiro框架提供的方式进行认证操作
     */
    public String login(){
        //从Session中获取生成的验证码
        String validatecode = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
        //校验验证码是否输入正确
        if(StringUtils.isNotBlank(checkcode) && checkcode.equals(validatecode)){
            //使用shiro框架提供的方式进行认证操作
            Subject subject = SecurityUtils.getSubject();//获得当前用户对象,状态为“未认证”
            AuthenticationToken token = new UsernamePasswordToken(model.getUsername(), MD5Utils.md5(model.getPassword()));//创建用户名密码令牌对象
            try{
                subject.login(token);
            }catch(Exception e){
                e.printStackTrace();
                return "login";
            }
            TUser user = (TUser) subject.getPrincipal();
            ServletActionContext.getRequest().getSession().setAttribute("loginUser", user);
            return "home";
        }else{
            //输入的验证码错误,设置提示信息,跳转到登录页面
            this.addActionError("输入的验证码错误!");
            return "login";
        }
    }

    第六步:自定义realm

    public class BOSRealm extends AuthorizingRealm {
    
        @Autowired
        private IUserDao userDao;
    
        //认证方法
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token){
            System.out.println("realm中的认证方法执行了。。。。");
            UsernamePasswordToken mytoken = (UsernamePasswordToken)token;
            String username = mytoken.getUsername();
            //根据用户名查询数据库中的密码
            TUser user = userDao.findUserByUserName(username);
            if(user == null){
                //用户名不存在
                return null;
            }
            //如果能查询到,再由框架比对数据库中查询到的密码和页面提交的密码是否一致;第一个参数是subject.getPrincipal的返回值类型,第二个是密码,第三个是任意字符串
            AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
            return info;
        }
    
        //授权方法
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            return null;  // retutn是return给安全管理器,return null的话会抛出异常
        }
    } 

    并注入给安全管理器

    <!--配置安全管理器-->
    <bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"/>
    </bean>
    
    
    <!--注册自定义的realm-->
    <bean name="bosRealm" class="cn.x5456.bos.web.realm.BOSRealm"/>
    

    二、使用shiro的方法注解方式权限控制

    第一步:在spring配置文件中开启shiro注解支持

    <!-- 开启shiro框架注解支持 -->
    <bean id="defaultAdvisorAutoProxyCreator"
          class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <!-- 必须使用cglib方式为Action对象创建代理对象 -->
        <!-- 原因:使用jdk版本代理的话,根本没有Action中的方法 -->
        <property name="proxyTargetClass" value="true"/>
    </bean>
    
    <!-- 配置shiro框架提供的切面类,用于创建代理对象 -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>

    第二步:在Action的方法上使用shiro注解

    第三步:在realm中进行授权

    //授权方法
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    
        // 获取用户对象
        TUser user1 = (TUser) SecurityUtils.getSubject().getPrincipal();
        TUser user2 = (TUser) principals.getPrimaryPrincipal();
        System.out.println(user1==user2);
    
        // TODO 根据用户对象查询数据库进行授权
        // 直接(不查数据库)为用户授权
        info.addStringPermission("staff-list");
    
        return info;
    }

    第四步:在struts.xml中配置全局异常捕获,当shiro框架抛出权限不足异常时,跳转到权限不足提示页面

    <global-results>
        <result name="login" type="redirect">/login.jsp</result>
        <result name="unauthorized" type="redirect">/redirect.jsp</result>
    </global-results>
    
    <global-exception-mappings>
        <exception-mapping exception="org.apache.shiro.authz.UnauthorizedException" result="unauthorized"/>
    </global-exception-mappings>

    三、使用shiro提供的页面标签方式权限控制

    第一步:在jsp页面中引入shiro的标签库

    <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

    第二步:使用shiro的标签控制页面元素展示

    四、总结

    URL拦截权限控制(基于过滤器实现)

    方法注解权限控制(基于代理技术实现)

     

    页面标签权限控制(标签技术实现)

    代码级别权限控制(基于代理技术实现)

     4、参数同名问题

    参数同名问题,会先给model赋值
    1)删除model中的字段
    2)将page从model中get出来,在给pagebean赋值

    5、EasyUI的combotree的使用

    combotree插件不能像ztree一样使用简单json

  • 相关阅读:
    个人收集
    30个提高Web程序执行效率的好经验
    如何进行有效的代码检查
    软件测试杂谈
    论dotnet应用程序通用开发方法的弊端
    给Linux增加硬盘的方法
    知识分子的生活态度
    深入认识敏捷开发和面向对象
    使用自定义主题让Windows Live Writer在本地预览语法高亮效果
    软件工程项目中数据库的作用以及敏捷开发
  • 原文地址:https://www.cnblogs.com/x54256/p/8604326.html
Copyright © 2020-2023  润新知