shiro安全框架的使用

    xiaoxiao2026-05-09  2

    Shiro的使用

    在WEB.XML中配置:shiro核心控制器 DelegatingFilterProxy

    applicationContext.xml 事务管理声明之前配置:开启cglib动态代理方式

    配置shiro的配置文件:基于spring

    Shiro配置文件:

     

             description>Shiro的配置</description>

      

       <!-- SecurityManager配置 -->

       <!-- 配置Realm -->

       <!-- 密码比较器 -->

       <!-- 代理如何生成?用工厂来生成Shiro的相关过滤器-->

       <!-- 配置缓存:ehcache缓存 -->

       <!-- 安全管理 -->

        <bean id="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

            <!--Single realm app.  If you have multiplerealms, use the 'realms' property instead. -->

            <property name="realm"ref="authRealm"/><!-- 引用自定义的realm -->

            <!-- 缓存 -->

            <property name="cacheManager"ref="shiroEhcacheManager"/>

        </bean>

     

        <!-- 自定义权限认证 -->

        <bean id="authRealm"class="cn.itcast.jk.shiro.AuthRealm[a1] ">

          <property name="userService"ref="userService"/>

          <!-- 自定义密码加密算法 -->

          <property name="credentialsMatcher"ref="passwordMatcher"/>

       </bean>

      

       <!-- 设置密码加密策略 md5hash -->

       <bean id="passwordMatcher"class="cn.itcast.jk.shiro.CustomCredentialsMatcher[a2] "/>

     

        <!-- filter-name这个名字的值来自于web.xmlfilter的名字 -->

        <bean id="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

            <property name="securityManager"ref="securityManager"/>

            <!--登录页面 -->

            <property name="loginUrl"value="/index.jsp"></property>

            <!-- 登录成功后 -->     

            <property name="successUrl"value="/home.action"></property>

            <property name="filterChainDefinitions">

                <!-- /**代表下面的多级目录也过滤 -->

                <value>

                /index.jsp* = anon

                /home* = anon

                /sysadmin/login/login.jsp* = anon

                /sysadmin/login/logout.jsp* = anon

                /login* = anon

                /logout* = anon

                /components/** = anon

                /css/** = anon

                /images/** = anon

                /js/** = anon

                /make/** = anon

                /skin/** = anon

                /stat/** = anon

                /ufiles/** = anon

                /validator/** = anon

                /resource/** = anon

                /** = authc

                /*.* = authc

                </value>

            </property>

        </bean>

     

        <!-- 用户授权/认证信息Cache, 采用EhCache 缓存 -->

        <bean id="shiroEhcacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">

            <property name="cacheManagerConfigFile"value="classpath:ehcache-shiro.xml[a3] "/>

        </bean>

     

        <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->

        <bean id="lifecycleBeanPostProcessor"class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

     

        <!-- 生成代理,通过代理进行控制 -->

        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"

              depends-on="lifecycleBeanPostProcessor">

            <property name="proxyTargetClass"value="true"/>

        </bean>

       

        <!-- 安全管理器 -->

        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

            <property name="securityManager"ref="securityManager"/>

        </bean>

     

     

    授权&管理 类

    public class AuthRealm extends AuthorizingRealm{

       private UserService userService;

       public voidsetUserService(UserService userService) {

          this.userService = userService;

       }

       /**

        * 授权

        */

       @Override

       protectedAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {

          User user = (User)pc.fromRealm(this.getName()).iterator().next();[a4] 

          //获取对象导航

          Set<Role> roles = user.getRoles();

          List<String> permissions = newArrayList<String>();

          for(Role role:roles){

             //遍历角色得到每个角色下的模块列表

             Set<Module> modules = role.getModules();

             //将模块名放入permissions

             for (Module module : modules) {

                permissions.add(module.getName());

             }

      

             SimpleAuthorizationInfo info = newSimpleAuthorizationInfo();

             info.addStringPermissions(permissions);

             return info;

          }

         

          return null;

       }

       /**

        * 认证

        */

       @Override

       protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token[a5] ) throwsAuthenticationException {

         

          UsernamePasswordToken upToken = (UsernamePasswordToken)token;[a6] 

         

          //查询用户

          String hql = "fromUser where userName=?";

          List<User> list = userService.find(hql, User.class, new String[]{upToken.getUsername()});

         

          //判断用户是否存在

          if(list!=null && list.size()>0){

             //获取用户名

             User user = list.get(0);

          //核心API

             SimpleAuthenticationInfo info = newSimpleAuthenticationInfo(user, user.getPassword(),

    this.getName()[a7] );[a8] 

             return info;//进入密码比较器

          }

          return null;

       }

     

    密码比较器:

      public classCustomCredentialsMatcher extendsSimpleCredentialsMatcher{

        //密码比较

        public booleandoCredentialsMatch(AuthenticationTokentoken, AuthenticationInfo info[a9] [a10] ){

            UsernamePasswordToken upToken =(UsernamePasswordToken)token;

            //将用户在界面输入的原始密码加密

            Object pwd = Encrypt.md5(new String(upToken.getPassword())[a11] , upToken.getUsername()[a12] );[a13] 

            //获取数据库中加密的密码

            Object dbPwd = info.getCredentials();

            return this.equals(pwd,dbPwd);//进行密码比较

        }

    }

     

     

    Action中的方法:

     

    try {

                Subject subject =SecurityUtils.getSubject();[a14] 

                //调用登录方法

                UsernamePasswordToken tokan = newUsernamePasswordToken(username, password);

                subject.login(tokan);//当这一代码执行时,就会自动跳入到AuthRealm中认证方法

                //登录成功时,shiro中取出用户的登录信息

                User user = (User) subject.getPrincipal();

            } catch (Exception e) {

                e.printStackTrace();

                request.put("errorInfo", "用户名或密码错误");

                return "login";

            }

     

     

    执行过程:

     

     

     


     [a1]自定义认证&权限路径

     [a2]自定义的密码比较器

     [a3]缓存的配置文件

     [a4]获取user对象

     [a5]存放用户名和密码

     [a6]把接口强制转换成它的实现类

     [a7]可为任意字符串,与授权中pc.fromRealm(this.getName()).iterator().next();中的this.getName()一致

     [a8]将用户,用户名,认证名称传入SimpleAuthenticationInfo中

     [a9]来自授权&认证的数据

     [a10]AuthRealm类 info对象穿过来的参数;token 是user对象,info是客户端传来的密码

     [a11]客户端传来的密码

     [a12]Salt 是一个任意的字符串,加密的一个参数

     [a13]调用工具类给密码加密

     [a14]获取subject对象

    转载请注明原文地址: https://ju.6miu.com/read-1309505.html
    最新回复(0)