溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Apache Shiro 認證、授權(quán)、加密和會話管理

發(fā)布時間:2020-07-16 03:16:32 來源:網(wǎng)絡(luò) 閱讀:1693 作者:攻城獅之旅 欄目:開發(fā)技術(shù)

官方解釋 :  

        Apache Shiro(日語“堡壘(Castle)”的意思)是一個強大易用的Java安全框架,提供了認證、授權(quán)、加密和會話管理功能,可為任何應(yīng)用提供安全保障 - 從命令行應(yīng)用、移動應(yīng)用到大型網(wǎng)絡(luò)及企業(yè)應(yīng)用。

Shiro為解決下列問題(我喜歡稱它們?yōu)閼?yīng)用安全的四要素)提供了保護應(yīng)用的API:

認證 - 用戶身份識別,常被稱為用戶“登錄”;

授權(quán) - 訪問控制;

密碼加密 - 保護或隱藏數(shù)據(jù)防止被偷窺;

會話管理 - 每用戶相關(guān)的時間敏感的狀態(tài)。

Shiro還支持一些輔助特性,如Web應(yīng)用安全、單元測試和多線程,它們的存在強化了上面提到的四個要素。

第一步:配置web.xml

<!-- 配置Shiro過濾器,先讓Shiro過濾系統(tǒng)接收到的請求 -->  <!-- 這里filter-name必須對應(yīng)applicationContext.xml中定義的<bean id="shiroFilter"/> -->  <!-- 使用[/*]匹配所有請求,保證所有的可控請求都經(jīng)過Shiro的過濾 -->  <!-- 通常會將此filter-mapping放置到最前面(即其他filter-mapping前面),以保證它是過濾器鏈中第一個起作用的 -->  
<filter>  
    <filter-name>shiroFilter</filter-name>  
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>  
        <!-- 該值缺省為false,表示生命周期由SpringApplicationContext管理,設(shè)置為true則表示由ServletContainer管理 -->  
        <param-name>targetFilterLifecycle</param-name>  
        <param-value>true</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>shiroFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>

第二步:配置spring-shiro.xml

    <!-- 繼承自AuthorizingRealm的自定義Realm,即指定Shiro驗證用戶登錄的類為自定義的ShiroDbRealm.java -->  
<bean id="myRealm" class="com.tyzq.common.ShiroRealm"/>  
    <!-- Shiro默認會使用Servlet容器的Session,可通過sessionMode屬性來指定使用Shiro原生Session -->  
    <!-- 即<property name="sessionMode" value="native"/>,詳細說明見官方文檔 -->
    <!-- 這里主要是設(shè)置自定義的單Realm應(yīng)用,若有多個Realm,可使用'realms'屬性代替 -->  
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
    <property name="realm" ref="myRealm"/>  
</bean>  
    <!-- Shiro主過濾器本身功能十分強大,其強大之處就在于它支持任何基于URL路徑表達式的、自定義的過濾器的執(zhí)行 -->  
    <!-- Web應(yīng)用中,Shiro可控制的Web請求必須經(jīng)過Shiro主過濾器的攔截,Shiro對基于Spring的Web應(yīng)用提供了完美的支持 -->  
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
    <!-- Shiro的核心安全接口,這個屬性是必須的 -->  
    <property name="securityManager" ref="securityManager"/>  
    <!-- 要求登錄時的鏈接(可根據(jù)項目的URL進行替換),非必須的屬性,默認會自動尋找Web工程根目錄下的"/login.jsp"頁面 -->  
    <property name="loginUrl" value="/"/>  
    <!-- 登錄成功后要跳轉(zhuǎn)的連接(本例中此屬性用不到,因為登錄成功后的處理邏輯在LoginController里面控制跳轉(zhuǎn)) -->  
    <!-- <property name="successUrl" value="/system/main"/> -->  
    <!-- 用戶訪問未對其授權(quán)的資源時,所顯示的連接 -->  
    <property name="unauthorizedUrl" value="/noauthority.jsp"/>  
    <!-- Shiro連接約束配置,即過濾鏈的定義 -->  
    <!-- anon:它對應(yīng)的過濾器里面是空的,什么都沒做,這里.do和.jsp后面的*表示參數(shù),比方說login.jsp?main這種 -->  
    <!-- authc:該過濾器下的頁面必須驗證后才能訪問,它是Shiro內(nèi)置的一個攔截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->  
    <property name="filterChainDefinitions">  
        <value>  
             /mydemo/login=anon  
             /mydemo/getVerifyCodeImage=anon  
             /main**=authc  
             /user/info**=authc  
        </value>  
    </property></bean>  
  <!-- 保證實現(xiàn)了Shiro內(nèi)部lifecycle函數(shù)的bean執(zhí)行 -->  
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
  <!-- 開啟Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP掃描使用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>

第三步:自定義的Realm類

public class ShiroRealm extends AuthorizingRealm{

	@Autowired
	private UserInfoService userInfoService;
	
	/**
	 * “授權(quán)”查詢回調(diào)函數(shù), 進行鑒權(quán)但緩存中無用戶的授權(quán)信息時調(diào)用.
	 * @param principals
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection collection) {
		SimpleAuthorizationInfo info = null;
		/*String username = (String) collection.fromRealm(getName()).iterator().next();
		/*User userInfo =	userService.getById(username);
		Criteria criteria=new Criteria();
		criteria.put("userId", userInfo.getId());
		if (userInfo != null) {
			//權(quán)限控制
			info = new SimpleAuthorizationInfo();
			List<MoKuai> moKuais=this.kuaiService.findListByUserId(criteria);
			String method = null;
			String permissioin = null;
			for (MoKuai item : moKuais) {
				permissioin = item.getPrivPermissioin();
					if(!StringHelper.isNullOrEmpty(permissioin)){
						permissioin = permissioin.trim();
						info.addStringPermission(permissioin);
					}
			}
		}*/
		return info;
	}

	/**
	 * “認證”回調(diào)函數(shù),登錄時調(diào)用.
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken) token;
		UserInfo userInfo =	userInfoService.getUserInfoByAccount(usernamePasswordToken.getUsername());
		SimpleAuthenticationInfo info = null;
		if (userInfo != null) {
			//其他驗證
			info =  new SimpleAuthenticationInfo(usernamePasswordToken.getUsername(), usernamePasswordToken.getPassword(), getName());
		}
		//身份認證驗證成功,返回一個AuthenticationInfo實現(xiàn);  
		return info;
	}
	
	/**
	 * 更新用戶授權(quán)信息緩存.
	 */
	public void clearCachedAuthorizationInfo(String principal) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
		clearCachedAuthorizationInfo(principals);
	}

	/**
	 * 清除所有用戶授權(quán)信息緩存.
	 */
	public void clearAllCachedAuthorizationInfo() {
		Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
		if (cache != null) {
			for (Object key : cache.keys()) {
				cache.remove(key);
			}
		}
	}

}



向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI