• shiro学习记录(二)


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

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

    <!-- 引入shiro框架的依赖 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-all</artifactId>
                <version>1.2.2</version>
            </dependency>

    第二步:在web.xml中配置spring框架提供的用于整合shiro框架的过滤器(因为是ssh框架,一定要放在structs过滤器前面)

    <!-- 配置spring框架提供的用于整合shiro框架的过滤器 -->
      <filter>
          <filter-name>shrioFilter</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>shrioFilter</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
                    /image/** = anon
                    /validatecode.jsp* = anon
                    /login.jsp = anon
                    /userAction_login.action = anon
                    /page_base_staff.action = perms["staff-list"]<!-- perms过滤器,可以判断是否存在逻辑staff-list -->
                    /* = authc<!-- 过滤器别名,判断当前用户是否认证 -->
                </value>
            </property>
        </bean>

    框架提供的过滤器:

     

    第四步:配置安全管理器

    <!-- 注册安全管理器对象 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" />
        

    第五步:修改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;
                }
                User user = (User) 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;
        
        //授权方法
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    
            return null;
        }
    
        //认证方法
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("自定义的realm中认证方法执行了。。。。");
    
            UsernamePasswordToken passwordToken = (UsernamePasswordToken) token;
            //获取页面输入的用户名
            String username = passwordToken.getUsername();
            //根据用户名查询数据库中的密码
            User user = userDao.findUserByUserName(username);
            if (user == null) {
                //页面输入用户名不存在
                return null;
            }
            //简单认证信息对象
            AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassWord(), this.getName());
            //框架负责比对数据库中的密码和页面输入的密码是否一致
            return info;
        }
    
    }

     2.在realm中实现授权

     在BOSRealm中实现授权

    //授权方法
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //为用户授权
            info.addStringPermission("staff-list");
            
            //TODO 后期需要修改为登录用户查询数据库,获取实际对应的权限
            return info;
        }

     3.使用shiro的方法注解方式权限控制

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

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

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

    @RequiresPermissions("staff-delete")//执行这个方法,需要当前用户具有staff-delete的权限
        public String delBatchStaff() {
            staffService.delBatchStaff(ids);
            return LIST;
        }

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

    <!-- 配置全局结果集 -->
            <global-results>
                <result name="login">/login.jsp</result>
                <result name="unauthorized">/unauthorized.jsp</result>
            </global-results>
            
            <global-exception-mappings>
                <exception-mapping result="unauthorized" exception="org.apache.shiro.authz.UnauthorizedException" />
            </global-exception-mappings>

     4.总结shiro框架提供的权限控制方式

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

    <!-- 配置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
                    /image/** = anon
                    /validatecode.jsp* = anon
                    /login.jsp = anon
                    /userAction_login.action = anon
                    /page_base_staff.action = perms["staff-list"]<!-- perms过滤器,可以判断是否存在逻辑staff-list -->
                    /* = authc<!-- 过滤器别名,判断当前用户是否认证 -->
                </value>
            </property>
        </bean>

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

    @RequiresPermissions("staff-delete")//执行这个方法,需要当前用户具有staff-delete的权限
        public String delBatchStaff() {
            staffService.delBatchStaff(ids);
            return LIST;
        }

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

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

  • 相关阅读:
    数据库进阶系列之二:细说数据库范式
    ORACLE HANDBOOK系列之三:树状结构查询(Hierarchical Queries)
    Tips&Tricks系列八:Fail to convert .vsmid,.testrunconfig
    Java基础系列之四:Remote Debug入门示例
    Java基础系列之五:Spring使用入门示例
    数据库进阶系列之三:使用Logminer解析Oracle日志
    ORACLE HANDBOOK系列之四:批量SQL(BULK SQL)
    Tips&Tricks系列九:数据库外键的两个细节
    Tips&Tricks系列六:ADO.NET OracleConnection.ClearPool(conn)
    Java基础系列之六:CORBA入门示例
  • 原文地址:https://www.cnblogs.com/FanJava/p/9342811.html
Copyright © 2020-2023  润新知