shiro安全框架

原地址:http://blog.csdn.net/ityqing/article/details/52220923


  Shiro的使用

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

applicationContext.xml 事務管理聲明之前配置:開啓cglib動態代理方式

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

Shiro配置文件:

 

         description>Shiro的配置</description>

  

   <!-- SecurityManager配置 -->

   <!-- 配置Realm -->

   <!-- 密碼比較器 -->

   <!-- 代理如何生成?用工廠來生成Shiro的相關過濾器-->

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

   <!-- 安全管理 -->

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

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

        <propertyname="realm"ref="authRealm"/><!--引用自定義的realm -->

        <!-- 緩存 -->

        <propertyname="cacheManager"ref="shiroEhcacheManager"/>

    </bean>

 

    <!--自定義權限認證 -->

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

      <propertyname="userService"ref="userService"/>

      <!--自定義密碼加密算法 -->

      <propertyname="credentialsMatcher"ref="passwordMatcher"/>

   </bean>

  

   <!-- 設置密碼加密策略 md5hash -->

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

 

    <!-- filter-name這個名字的值來自於web.xmlfilter的名字 -->

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

        <propertyname="securityManager"ref="securityManager"/>

        <!--登錄頁面 -->

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

        <!-- 登錄成功後 -->     

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

        <propertyname="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 緩存 -->

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

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

    </bean>

 

    <!--保證實現了Shiro內部lifecycle函數的bean執行 -->

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

 

    <!--生成代理,通過代理進行控制 -->

    <beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"

          depends-on="lifecycleBeanPostProcessor">

        <propertyname="proxyTargetClass"value="true"/>

    </bean>

   

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

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

        <propertyname="securityManager"ref="securityManager"/>

    </bean>

 


 

授權&管理 類

publicclass AuthRealm extends AuthorizingRealm{

   private UserServiceuserService;

   publicvoidsetUserService(UserService userService) {

      this.userService =userService;

   }

   /**

    * 授權

    */

   @Override

   protectedAuthorizationInfo doGetAuthorizationInfo(PrincipalCollectionpc) {

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

      //獲取對象導航

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

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

      for(Rolerole:roles){

         //遍歷角色得到每個角色下的模塊列表

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

         //將模塊名放入permissions

         for (Modulemodule :modules) {

            permissions.add(module.getName());

         }

  

         SimpleAuthorizationInfo info =newSimpleAuthorizationInfo();

        info.addStringPermissions(permissions);

         returninfo;

      }

     

      returnnull;

   }

   /**

    * 認證

    */

   @Override

   protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationTokentoken[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

         SimpleAuthenticationInfoinfo =newSimpleAuthenticationInfo(user,user.getPassword(),

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

         returninfo;//進入密碼比較器

      }

      returnnull;

   }

 

密碼比較器:

  public classCustomCredentialsMatcherextendsSimpleCredentialsMatcher{

    //密碼比較

    publicbooleandoCredentialsMatch(AuthenticationTokentoken,AuthenticationInfoinfo[a9] [a10] ){

        UsernamePasswordToken upToken =(UsernamePasswordToken)token;

        //將用戶在界面輸入的原始密碼加密

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

        //獲取數據庫中加密的密碼

        Object dbPwd = info.getCredentials();

        returnthis.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 (Exceptione) {

            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對象

發佈了31 篇原創文章 · 獲贊 11 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章