1. 程式人生 > >基於BOS系統的Shiro許可權框架基本使用

基於BOS系統的Shiro許可權框架基本使用

目錄

1.Shiro框架的基本概念

Shiro框架的核心功能有4個,即認證、授權、會話管理、加密,shiro基本使用這一方面我們主要討論認證與授權兩個基本用法。認證,顧名思義,即登陸時期資料庫使用者物件與表單的使用者物件比對,若對比成功,則登陸成功。授權,即登陸之後當前該使用者能訪問哪些請求,不能訪問哪些請求,這些請求也是從資料庫中查詢的。

 Application Code:應用程式程式碼,由開發人員負責開發

Subject:框架提供的介面,代表當前認證物件

SecurityManager:框架提供的介面,代表安全管理器物件

Realm:可以開發人員編寫,框架也提供一些,類似於DAO,使用者訪問許可權資料

2.Shiro的maven依賴與spring配置

2.1shiro的maven依賴

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

2.2Shiro的spring配置

(1)在web.xml中配置spring框架提供的用於整合shiro框架的過濾器

<!-- 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>

(2)整合Spring,配置bean:shiroFilter

<!-- 配置shiro框架的過濾器工廠物件 -->
   <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
      <!-- 注入安全管理器物件 -->
      <property name="securityManager" ref="securityManager" />
      <!-- 注入相關頁面訪問URL -->
      <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>

(3)註冊安全管理器物件

<!-- 註冊安全管理器物件 -->
   <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" />

(4)Controller層編寫login方法,使用shiro提供的方式進行許可權認證

public String login() {
      /**
       * 校驗驗證碼
       */
      //獲取正確的驗證碼
      String trueCode = (String) ActionContext.getContext().getSession().get("key");
      //驗證碼校驗不通過
      if(trueCode != null && !trueCode.equals(checkCode)) {
         this.addActionError("驗證碼錯誤");
         return LOGIN;
      }else {//驗證碼正確
         //使用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;
         }
         return HOME;
      }
   }

如果認證不成功,Shiro會丟擲異常,此時我們在表現層需要處理異常。

(5)自定義Realm,配置bean並注入安全管理器

/**
 * 自定義realm
* Title: BOSRealm <p>
* Description:   <p>
* @author Tianyu Xiao 
* @date 2018年10月23日
 */
public class BOSRealm extends AuthorizingRealm{
   @Autowired
   private IUserDao userDao;
 
   /**
    * 授權
    */
   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
      // TODO Auto-generated method stub
      return null;
   }
  /**
    * 認證
    */
   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
     // TODO Auto-generated method stub
      return null;
   }
}

配置spring:

<!-- 註冊安全管理器物件 -->
   <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" >
      <property name="realm" ref="bosRealm" />
   </bean>
   <!-- 註冊realm -->
   <bean id="bosRealm" class="com.itheima.bos.realm.BOSRealm"></bean>

3.Shiro的認證

登陸時認證的java程式碼在2.2(4)中已經完成,我們只需要在Realm中完成Shiro的認證即可。

編寫Realm中的程式碼:

/**
	 * 認證
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken myToken = (UsernamePasswordToken) token;
		String username = myToken.getUsername();
		//根據使用者名稱查詢密碼
		User user = userDao.findUserByUsername(username);
		if(user == null) {
			//使用者不存在
			return null;//shiro 會丟擲異常
		}
		//如果能查詢到,再由框架比對資料庫中查詢到的密碼和頁面提交的密碼是否一致
		AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
		return info;
	}

4.Shiro的授權

4.1資料庫準備工作

4.2在Realm中完成授權

/**
    * 授權
    */
   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
     
      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      //獲取當前登陸的使用者物件
      User user = (User) SecurityUtils.getSubject().getPrincipal();
      //根據當前使用者查詢資料庫,獲取實際對應的許可權
      List<Function> functionList = null;
      //如果是系統的內建賬號(所有許可權都可以訪問)
      if(user.getUsername().equals("admin")) {
         functionList = functionDao.findAll();
      }else {//是基本通用使用者
         functionList = functionDao.findFunctionByUserId(user.getId());
      }
      //為當前的使用者授權
      for (Function function : functionList) {
         info.addStringPermission(function.getCode());
      }
      return info;
   }

5.shiro框架提供的許可權控制方式

(1)URL攔截許可權控制(基於過濾器實現)

(2)方法註解許可權控制(基於代理技術實現)

(3)頁面標籤許可權控制(標籤技術實現)