Shiro (包含權限知足其中一個就經過的用法)

方法/步驟

  1. web.xml添加配置web


    <!-- shiro過濾器 -->spring

     <filter>數據庫

      <filter-name>shiroFilter</filter-name>apache

      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>緩存

      <init-param>安全

       <param-name>targetFilterLifecycle</param-name>app

       <param-value>true</param-value>ide

      </init-param>ui

     </filter>url

     <filter-mapping>

      <filter-name>shiroFilter</filter-name>

      <url-pattern>/*</url-pattern>

     </filter-mapping>

  2. shiro與spring整合配置


    <!-- 使用shiro安全檢查註解 -->

     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" />

     

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

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

     </bean>



     <!-- shiro的生命週期處理器 -->

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

     

     <!-- shiro自帶的密碼匹配器(用來校驗密碼足夠了) -->

      <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.SimpleCredentialsMatcher"></bean> 

     <!-- security datasource: -->

     <bean id="myRealm" class="cc.eguid.service.shiro.MyRealm">

      <property name="credentialsMatcher" ref="credentialsMatcher"/><!-- 密碼匹配器 -->

            <property name="cachingEnabled" value="false"/><!-- 禁止緩存 -->

     </bean>

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

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

      <property name="realm" ref="myRealm" />

     </bean>

     <!-- shiro過濾器 -->

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

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

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

      <!-- 身份認證失敗跳轉的地址 -->

      <property name="loginUrl" value="/login/" />

      <!-- 身份認證成功跳轉的地址 -->

      <property name="successUrl" value="/" />

      <!-- 權限認證失敗跳轉的地址 -->

      <property name="unauthorizedUrl" value="/login/unauthorized" />

      <property name="filterChainDefinitions">

       <!--anon 表示匿名訪問,不須要認證以及受權 -->

       <!--authc表示須要認證 沒有進行身份認證是不能進行訪問的 -->

       <!--authc,roles[admin]表示是admin角色的用戶才能訪問 -->

       <value>

        /static/** = anon

        /login/** = anon

        /common/** = anon

        /admin/** = authc,roles[admin]

        /* = authc

        /** = authc

       </value>

      </property>

     </bean>

     

  3. realm和自定義密碼校驗器實現


    public class MyRealm extends AuthorizingRealm{

     Logger log=Logger.getLogger(MyRealm.class);

     

     @Autowired

        private UserService userService;//這是本身實現的用戶信息操做類,實現用戶信息,用戶角色信息、用戶權限信息查詢功能

     

     @Override

     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

      UserInfo user = (UserInfo) principals.getPrimaryPrincipal();

      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

      // 查詢角色信息

      Collection<String> roles = userService.findRoles(user);

      info.addRoles(roles);

      log.info("shiro獲取用戶所屬角色列表:"+roles);

      // 查詢權限信息

      Collection<String> permissions = userService.findPermissions(user.getSystemuserid());

      info.addStringPermissions(permissions);

      log.info("shiro獲取用戶權限列表:"+permissions);

      return info;

     }

     

     @Override

     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException{

      //用戶輸入的用戶名密碼

      String loginname=  token.getPrincipal().toString();

      Object password=token.getCredentials();

      log.info("shiro正在處理嘗試登陸的用戶信息:"+loginname+",密碼:"+new String((char[])password));

      //數據庫中的用戶信息

      UserInfo user =userService.queryUserInfoByLoginName(loginname);

      if(user==null||CommonUtil.isNull(user.getLoginusername(),user.getPassword(),user.getSystemuserid())){

       return null;

      }

      log.info("shiro獲取到當前用戶嘗試登陸的真實數據:"+user.getLoginusername()+",密碼:"+user.getPassword());

      //數據庫中的正確的帳戶信息

      AuthenticationInfo accountInfo =new SimpleAuthenticationInfo(user, user.getPassword(),getName());

        

      //本身獲取密碼驗證器(因爲shiro實現的密碼校驗方法是密碼錯誤會直接拋異常,不採用,因此改爲直接手動校驗)

      CredentialsMatcher matcher=getCredentialsMatcher();

      if(matcher==null){

       log.error("沒有配置密碼匹配器");

       return null;

      }

      //校驗密碼

      if(matcher.doCredentialsMatch(token,accountInfo)){

       return accountInfo;//校驗經過,返回帳號信息

      }

      

      return null;

     }

     

     

    }

  4. 自定義密碼校驗器


    /**

     * 自定義shiro密碼匹配(密碼是在md5散列值的基礎上再次進行md5加鹽操做,加鹽值不保存在數據庫,而是放在配置文件中)

     * @author eguid

     *

     */

    public class MyCredentialsMatcher extends CodecSupport implements CredentialsMatcher {

     private static final Logger log = LoggerFactory.getLogger(MyCredentialsMatcher.class);

     

     protected Object getCredentials(AuthenticationToken token) {

      return token.getCredentials();

     }

     

     protected Object getCredentials(AuthenticationInfo info) {

      return info.getCredentials();

     }

     

     @Autowired

     private CommonConfigs commonConfigs;

     /**

      * 驗證密碼

      *

      * @param tokenCredentials

      * @param accountCredentials

      * @return

      */

     protected boolean equals(Object tokenCredentials, Object accountCredentials) {

      if (log.isDebugEnabled()) {

       log.debug("Performing credentials equality check for tokenCredentials of type ["

         + tokenCredentials.getClass().getName() + " and accountCredentials of type ["

         + accountCredentials.getClass().getName() + "]");

      }

      if (isByteSource(tokenCredentials) && isByteSource(accountCredentials)) {

       if (log.isDebugEnabled()) {

        log.debug("Both credentials arguments can be easily converted to byte arrays.  Performing "

          + "array equals comparison");

       }

       byte[] tokenBytes = toBytes(tokenCredentials);

       byte[] accountBytes = toBytes(accountCredentials);

       return MessageDigest.isEqual(tokenBytes, accountBytes);

      } else {

       return accountCredentials.equals(tokenCredentials);

      }

     }

     

     public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

      Object tokenCredentials = getCredentials(token);

      Object accountCredentials = getCredentials(info);

      String account=String.valueOf((char[])tokenCredentials);

      if(commonConfigs.getMd5salt()==null){

       if (log.isDebugEnabled()) {

        log.debug("配置文件中的加鹽值爲空,沒法進行密碼匹配,請確認配置文件是否在指定位置或配置指定加鹽值");

       }

       return false;

      }

      String saltaccount=MD5Util.getMD5(account, commonConfigs.getMd5salt());

      if (log.isDebugEnabled()) {

       log.debug("加鹽後的密碼:"+saltaccount);

      }

      return equals(accountCredentials, saltaccount.toCharArray());

     }

     

    }

  5. 註解使用及模板標籤使用

    一、註解使用
    @RequiresPermissions({"user:update:view"})//檢查操做權限
    @RequiresPermissions(value={"user:add","user:view"},logical=Logical.OR)//兩個操做權限其中一個知足條件便可經過檢查
    @RequiresRoles({"admin"})//檢查角色
    @RequiresRoles(value={"debug","admin"},logical=Logical.OR)//兩個角色其中一個角色知足條件便可

    @RequiresAuthentication//檢查是否經過shiro認證
    @RequiresGuest//不須要驗證
    @RequiresUser//檢查用戶是不是當前系統中的用戶

    二、標籤使用
    使用標籤須要先導入shiro的標籤庫<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
    (1)顯示用戶身份信息
    <shiro: principal/>
    默認調用Subject.getPrincipal()獲取

    <shiro:principal property="username"/>
    至關於((User)Subject.getPrincipals()).getUsername()

    (2)已登陸shiro用戶顯示

     <shiro:user> 
    歡迎[<shiro:principal/>]登陸,<a href="logout">退出</a> 
    <shiro:user>

    (3)匿名用戶訪問
    <shiro:guest>未通過shiro驗證的用戶(遊客,匿名用戶)</shiro:guest> 

    (4)已經在shiro登陸過的(已登陸用戶)

     <shiro:authenticated> 
        用戶[<shiro:principal/>]已身份驗證經過 
    <shiro:authenticated>

    (5)沒有在shiro登陸過的


     <shiro:notAuthenticated>
        未身份驗證(包括記住我)
    <shiro:notAuthenticated>

    (6)檢查角色

     <shiro:hasRole name="admin">
        用戶[<shiro:principal/>]擁有角色admin<br/>
    <shiro:hasRole>

    檢查任意角色(其中一個知足條件即經過,至關於OR)
     <shiro:hasAnyRoles name="admin,user">
        用戶[<shiro:principal/>]擁有角色admin或user<br/>
    <shiro:hasAnyRoles>

    不具備角色(反向判斷)
     <shiro:lacksRole name="abc">
        用戶[<shiro:principal/>]不具備角色abc<br/>
    <shiro:lacksRole>

    (7)操做權限判斷

     <shiro:hasPermission name="user:create"> 
        用戶[<shiro:principal/>]擁有權限user:create<br/> 
    <shiro:hasPermission>   

    不具備操做權限(反向判斷)


     <shiro:lacksPermission name="org:create"> 
        用戶[<shiro:principal/>]沒有權限org:create<br/> 
    <iro:lacksPermission> 

    END
相關文章
相關標籤/搜索