溫馨提示×

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

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

什么是Shiro驗(yàn)證

發(fā)布時(shí)間:2021-10-19 17:41:19 來(lái)源:億速云 閱讀:116 作者:柒染 欄目:大數(shù)據(jù)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)什么是Shiro驗(yàn)證,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

shiro驗(yàn)證:用戶需要提供系統(tǒng)理解和信任的某種身份證明(密碼、證書等),來(lái)證明自己可以登錄該系統(tǒng)。
在驗(yàn)證階段需要先理解幾個(gè)術(shù)語(yǔ):

  • Subject(主體)- 可以通俗的理解為訪問(wèn)應(yīng)用程序的用戶。只不過(guò)這個(gè)用戶可以是人、第三方進(jìn)程等等。

  • Principals(身份)- 主體的唯一標(biāo)識(shí)屬性。例如:身份證號(hào)碼、手機(jī)號(hào)、郵箱等等。

  • Credentials(憑證)- 只有主體知道的安全值。例如:密碼、數(shù)字證書等等。

  • Realms(領(lǐng)域)- 數(shù)據(jù)訪問(wèn)對(duì)象。用來(lái)獲取Principals和Credentials。例如:用戶名和密碼存放在.ini文件中,可以通過(guò)IniRealm獲取用戶名和密碼、用戶名和密碼存放在數(shù)據(jù)庫(kù)中,可以通過(guò)JdbcRealm獲取用戶名和密碼等等。

  • AuthenticationToken(驗(yàn)證令牌)- 結(jié)合Principals(身份)和Credentials(憑證)可獲得的用戶身份令牌。

  • Authenticator (驗(yàn)證者) - 驗(yàn)證用戶驗(yàn)證令牌是否滿足要求的科目。

  • AuthenticationStrategy(身份驗(yàn)證策略)- 表示以何種策略驗(yàn)證用戶身份。

如下是從官網(wǎng)獲取的驗(yàn)證架構(gòu)圖:
什么是Shiro驗(yàn)證

  • 步驟1:收集主題提交的 Principals 和 Credentials 得到 Token,應(yīng)用程序代碼調(diào)用Subject.login方法,傳入 Token 以進(jìn)行身份驗(yàn)證動(dòng)作。

  • 步驟2:Subject實(shí)例,通常是 DelegatingSubject(或子類)通過(guò)調(diào)用 securityManager.login(token)將實(shí)際的身份驗(yàn)證工作委托給 SecurityManager 處理

  • 步驟3:SecurityManager 作為基本的組件,接收 Token 然后通過(guò)調(diào)用 authenticate(token)將其委托給 Authenticator。Authenticator 幾乎總是實(shí)例 ModularRealmAuthenticator,它支持在身份驗(yàn)證期間協(xié)調(diào)一個(gè)或多個(gè) Realm 實(shí)例。

  • 步驟4:如果為應(yīng)用配置了多個(gè) Realm ,則 ModularRealmAuthenticator 實(shí)例將使用其配置的 AuthenticationStrategy 啟動(dòng)多領(lǐng)域身份驗(yàn)證嘗試。在調(diào)用 Realms 進(jìn)行身份驗(yàn)證之前,期間或者之后,將調(diào)用 AuthenticationStrategy 以允許它對(duì)每個(gè) Realm 的結(jié)果做出反應(yīng)。

  • 步驟5:將咨詢每個(gè) realm 以查看是否支持已提交的 AuthenticationToken。如果是這樣,將使用提交的 Token 調(diào)用 realm 的getauthenticationfo方法。getauthenticationfo方法有效地表示該特定領(lǐng)域的單一身份驗(yàn)證嘗試。

接下來(lái)就開(kāi)始使用ShiroAPI完成驗(yàn)證操作了。
環(huán)境準(zhǔn)備:

本文使用 Maven 構(gòu)建,因此需要一點(diǎn) Maven 知識(shí)。首先準(zhǔn)備環(huán)境依賴:

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.3.2</version>
    </dependency>
</dependencies>

添加 junit 和 shiro-core 依賴即可。

初識(shí):登錄 / 退出

1、首先準(zhǔn)備一些用戶身份 / 憑據(jù)(shiro.ini)

[users]
zhangsan=123
lisi=123

2、測(cè)試用例(com.luther.shiro.authenticator.AuthenticateTest)

/**
 * 底層默認(rèn)使用ModularRealmAuthenticator驗(yàn)證模塊(多realm驗(yàn)證) <br/>
 * AtLeastOneSuccessfulStrategy驗(yàn)證策略(只要有一個(gè)域成功進(jìn)行身份驗(yàn)證,
 * 		則認(rèn)為成功。否則失敗。會(huì)返回所有成功的用戶標(biāo)識(shí))
 * @author luther
 * @time 2019年7月5日  上午9:58:39
 */
@Test
public void testHelloWorld() {
	// 使用Ini配置文件初始化SecurityManager
	Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
	// 得到SecurityManager實(shí)例 并綁定給SecurityUtils
	SecurityManager securityManager = factory.getInstance();
	SecurityUtils.setSecurityManager(securityManager);
	
	// 得到Subject及創(chuàng)建用戶名/密碼身份驗(yàn)證Token(即用戶身份/憑證)
	Subject subject = SecurityUtils.getSubject();
	UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
	// 記住用戶
	token.setRememberMe(Boolean.TRUE);
	
	try {
		// 登錄
		subject.login(token);
		System.out.println("登錄成功");
	} catch (AuthenticationException e) {
		System.err.println("登錄失敗,失敗原因:");
		e.printStackTrace();
	}
	
	assertTrue("用戶已驗(yàn)證成功", subject.isAuthenticated());
	
	// 退出
	subject.logout();
}

Realm
realm 接口結(jié)構(gòu)如下,其下方法有: 什么是Shiro驗(yàn)證

String getName(); //返回一個(gè)唯一的Realm名字
boolean supports(AuthenticationToken token); //判斷此Realm是否支持此Token
AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;  //根據(jù)Token獲取認(rèn)證信息

其中主要默認(rèn)實(shí)現(xiàn)如下:
org.apache.shiro.realm.text.IniRealm:從ini文件獲取用戶權(quán)限等信息。
org.apache.shiro.realm.text.PropertiesRealm:從properties文件獲取用戶權(quán)限等信息。
org.apache.shiro.realm.jdbc.JdbcRealm:從數(shù)據(jù)庫(kù)獲取用戶權(quán)限等信息。
以后開(kāi)發(fā)一般繼承 AuthorizingRealm(授權(quán))抽象類即可;其繼承了 AuthenticatingRealm(即身份驗(yàn)證),而且也間接繼承了 CachingRealm(帶有緩存實(shí)現(xiàn))。

一、單 Realm 配置

1、自定義 Realm 實(shí)現(xiàn)(com.luther.shiro.realm.MyRealm1):

public class MyRealm1 implements Realm {

	@Override
	public String getName() {
		return this.getClass().getName();
	}

	@Override
	public boolean supports(AuthenticationToken token) {
		// 只支持UsernamePasswordToken
		return token instanceof UsernamePasswordToken;
	}

	@Override
	public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		
		// 得到用戶名
		String username = usernamePasswordToken.getUsername();
		// 得到密碼
		String password = new String(usernamePasswordToken.getPassword());
		
		// 戶名錯(cuò)誤
		if (!"zhangsan".equals(username)) {
			throw new UnknownAccountException(); 
		}

		// 密碼錯(cuò)誤
		if (!"123".equals(password)) {
			throw new IncorrectCredentialsException(); 
		}

		System.out.println("用戶" + username + "驗(yàn)證成功");

		// 返回
		return new SimpleAccount(username, password, getName());
	}
}

2、ini 配置文件指定自定義 Realm 實(shí)現(xiàn) (shiro-realm.ini)

[main]
#聲明一個(gè)realm
myRealm1=com.luther.shiro.realm.MyRealm1
#指定securityManager的realms實(shí)現(xiàn),通過(guò) $name 來(lái)引入之前的 realm 定義
securityManager.realms=$myRealm1

3、測(cè)試用例請(qǐng)參考 com.luther.shiro.authenticator.AuthenticateTest 的testSingleRealm 測(cè)試方法,此方法和 testHelloWorld 除了配置文件其它沒(méi)有差異。

二、多 Realm 配置

1、ini 配置文件(shiro-multi-realm.ini)

[main]
#聲明一個(gè)realm
myRealm1=com.luther.shiro.realm.MyRealm1
#聲明一個(gè)realm
myRealm2=com.luther.shiro.realm.MyRealm2
#指定securityManager的realms實(shí)現(xiàn),通過(guò) $name 來(lái)引入之前的 realm 定義
securityManager.realms=$myRealm2,$myRealm1

#此例子中顯視的指定了順序?yàn)閙yRealm2,myRealm1。(可以少指定,比如只指定myRealm2,則myRealm1會(huì)被忽略)
#如果不指定securityManager.realms,則會(huì)按realm的聲明(無(wú)需設(shè)置 realms 屬性,其會(huì)自動(dòng)發(fā)現(xiàn))順序來(lái),此處即為myRealm1,myRealm2。

2、測(cè)試用例請(qǐng)參考 com.luther.shiro.authenticator.AuthenticateTest 的 testMutiRealm 測(cè)試方法。

Authenticator 及 AuthenticationStrategy

一、Authenticator 及 AuthenticationStrategy簡(jiǎn)介
Authenticator 的職責(zé)是驗(yàn)證用戶帳號(hào),是 Shiro API 中身份驗(yàn)證核心的入口點(diǎn)(默認(rèn)實(shí)現(xiàn)為 ModularRealmAuthenticator ),其方法定義為:

public AuthenticationInfo authenticate(AuthenticationToken authenticationToken) throws AuthenticationException;

如果驗(yàn)證成功,將返回 AuthenticationInfo 驗(yàn)證信息;此信息中包含了身份及憑證;如果驗(yàn)證失敗將拋出相應(yīng)的 AuthenticationException 實(shí)現(xiàn)。

AuthenticationStrategy 則是 Authenticator 進(jìn)行驗(yàn)證時(shí)的驗(yàn)證策略 (默認(rèn)實(shí)現(xiàn)為:AtLeastOneSuccessfulStrategy),Shiro API 自帶的策略有以下三種:
FirstSuccessfulStrategy:只要有一個(gè) Realm 驗(yàn)證成功即可,只返回第一個(gè) Realm 身份驗(yàn)證成功的認(rèn)證信息,其他的忽略。
AtLeastOneSuccessfulStrategy:只要有一個(gè) Realm 驗(yàn)證成功即可,和 FirstSuccessfulStrategy 不同,返回所有 Realm 身份驗(yàn)證成功的認(rèn)證信息。
AllSuccessfulStrategy:所有 Realm 驗(yàn)證成功才算成功,且返回所有 Realm 身份驗(yàn)證成功的認(rèn)證信息,如果有一個(gè)失敗就失敗了。

二、Authenticator 及 AuthenticationStrategy演示
假設(shè)我們有三個(gè) realm:
myRealm1: 用戶名/密碼為 zhangsan/123 時(shí)成功,且返回身份/憑據(jù)為 zhangsan/123;
myRealm2: 用戶名/密碼為 lisi/123 時(shí)成功,且返回身份/憑據(jù)為 lisi/123;
myRealm3: 用戶名/密碼為 zhangsan/123 時(shí)成功,且返回身份/憑據(jù)為 zhangsan.qq/123

1、通用化登錄邏輯

private void authentition(String iniConfigPath, String username, String password) {
	// 使用Ini配置文件初始化SecurityManager
	Factory<SecurityManager> factory = new IniSecurityManagerFactory(iniConfigPath);
	// 得到SecurityManager實(shí)例 并綁定給SecurityUtils
	SecurityManager securityManager = factory.getInstance();
	SecurityUtils.setSecurityManager(securityManager);
	
	// 得到Subject及創(chuàng)建用戶名/密碼身份驗(yàn)證Token(即用戶身份/憑證)
	Subject subject = SecurityUtils.getSubject();
	UsernamePasswordToken token = new UsernamePasswordToken(username, password);
	// 記住用戶
	token.setRememberMe(Boolean.TRUE);
	
	try {
		// 登錄
		subject.login(token);
		System.out.println("用戶zhangsan登錄成功,其身份標(biāo)識(shí)為" + subject.getPrincipals());
	} catch (AuthenticationException e) {
		System.err.println("登錄失敗,失敗原因:");
		e.printStackTrace();
	}
	
	assertTrue("用戶已驗(yàn)證成功", subject.isAuthenticated());
	
	// 退出
	subject.logout();
}

2、測(cè)試 AtLeastOneSuccessfulStrategy
2.1 ini 配置文件 (shiro-firstSuccessfulStrategy.ini)

[main]
#指定securityManager的authenticator實(shí)現(xiàn),可以不指定,因?yàn)槠淠J(rèn)實(shí)現(xiàn)就是ModularRealmAuthenticator
#authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
#securityManager.authenticator=$authenticator

#指定securityManager.authenticator的authenticationStrategy,可以不指定,因?yàn)槠淠J(rèn)實(shí)現(xiàn)就是AtLeastOneSuccessfulStrategy
#authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
#securityManager.authenticator.authenticationStrategy=$authenticationStrategy

#聲明一個(gè)realm
myRealm1=com.luther.shiro.realm.MyRealm1
#聲明一個(gè)realm
myRealm2=com.luther.shiro.realm.MyRealm2
#聲明一個(gè)realm
myRealm3=com.luther.shiro.realm.MyRealm3
#指定securityManager的realms實(shí)現(xiàn),通過(guò) $name 來(lái)引入之前的 realm 定義
securityManager.realms=$myRealm3,$myRealm2,$myRealm1

2.2 測(cè)試代碼

/**
 * 演示AtLeastOneSuccessfulStrategy的效果
 * 每個(gè)realm都會(huì)進(jìn)行驗(yàn)證,并返回全部的成功用戶標(biāo)識(shí)
 * @author luther
 * @time 2019年7月5日  上午11:30:24
 */
@Test
public void testAtLeastOneSuccessfulStrategy() {
	authentition("classpath:shiro-atLeastOneSuccessfulStrategy.ini", "zhangsan", "123");
}

2.3 測(cè)試結(jié)果

開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm3
com.luther.shiro.realm.MyRealm3 - 用戶zhangsan驗(yàn)證成功
開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm2
開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm1
com.luther.shiro.realm.MyRealm1 - 用戶zhangsan驗(yàn)證成功
用戶zhangsan登錄成功,其身份標(biāo)識(shí)為zhangsan.qq,zhangsan

即 PrincipalCollection 包含了 zhangsan 和 zhangsan.qq 身份信息。

3、測(cè)試 AllSuccessfulStrategy
3.1 ini 配置文件 (shiro-allSuccessfulStrategy.ini)

[main]
#指定securityManager的authenticator實(shí)現(xiàn),可以不指定,因?yàn)槠淠J(rèn)實(shí)現(xiàn)就是ModularRealmAuthenticator
#authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
#securityManager.authenticator=$authenticator

#指定securityManager.authenticator的authenticationStrategy為AllSuccessfulStrategy
authenticationStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$authenticationStrategy

#聲明一個(gè)realm
myRealm1=com.luther.shiro.realm.MyRealm1
#聲明一個(gè)realm
myRealm2=com.luther.shiro.realm.MyRealm2
#聲明一個(gè)realm
myRealm3=com.luther.shiro.realm.MyRealm3
#指定securityManager的realms實(shí)現(xiàn),通過(guò) $name 來(lái)引入之前的 realm 定義
securityManager.realms=$myRealm3,$myRealm2,$myRealm1

3.2 測(cè)試代碼

/**
 * 演示AllSuccessfulStrategy的效果
 * 依次對(duì)每個(gè)realm進(jìn)行驗(yàn)證,驗(yàn)證通過(guò)下一個(gè),驗(yàn)證失敗,直接返回失敗驗(yàn)證原因,只有全部成功時(shí)才返回全部的用戶標(biāo)識(shí)
 * 每個(gè)realm都會(huì)進(jìn)行驗(yàn)證,并返回全部的成功用戶標(biāo)識(shí)
 * @author luther
 * @time 2019年7月5日  上午11:30:24
 */
@Test
public void testAllSuccessfulStrategy() {
	authentition("classpath:shiro-allSuccessfulStrategy.ini", "zhangsan", "123");
}

3.3 測(cè)試結(jié)果

開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm3
com.luther.shiro.realm.MyRealm3 - 用戶zhangsan驗(yàn)證成功
開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm2
登錄失敗,失敗原因:
org.apache.shiro.authc.UnknownAccountException
	at com.luther.shiro.realm.MyRealm2.getAuthenticationInfo(MyRealm2.java:42)
	······

4、測(cè)試 firstSuccessfulStrategy
4.1 ini 配置文件 (shiro-firstSuccessfulStrategy.ini)

[main]
#指定securityManager的authenticator實(shí)現(xiàn),可以不指定,因?yàn)槠淠J(rèn)實(shí)現(xiàn)就是ModularRealmAuthenticator
#authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
#securityManager.authenticator=$authenticator

#指定securityManager.authenticator的authenticationStrategy為FirstSuccessfulStrategy
authenticationStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$authenticationStrategy

#聲明一個(gè)realm
myRealm1=com.luther.shiro.realm.MyRealm1
#聲明一個(gè)realm
myRealm2=com.luther.shiro.realm.MyRealm2
#聲明一個(gè)realm
myRealm3=com.luther.shiro.realm.MyRealm3
#指定securityManager的realms實(shí)現(xiàn),通過(guò) $name 來(lái)引入之前的 realm 定義
securityManager.realms=$myRealm3,$myRealm2,$myRealm1

4.2 測(cè)試代碼

/**
 * 演示FirstSuccessfulStrategy的效果
 * 會(huì)對(duì)每個(gè)realm進(jìn)行驗(yàn)證,全部驗(yàn)證完后會(huì)返回驗(yàn)證成功的第一個(gè)用戶標(biāo)識(shí)(此處需注意,不是依次驗(yàn)證立馬返回,而是全部驗(yàn)證再返回)
 * @author luther
 * @time 2019年7月5日  上午11:30:24
 */
@Test
public void testFirstSuccessfulStrategy() {
	authentition("classpath:shiro-firstSuccessfulStrategy.ini", "zhangsan", "123");
}

4.3 測(cè)試結(jié)果

開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm3
com.luther.shiro.realm.MyRealm3 - 用戶zhangsan驗(yàn)證成功
開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm2
開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm1
com.luther.shiro.realm.MyRealm1 - 用戶zhangsan驗(yàn)證成功
用戶zhangsan登錄成功,其身份標(biāo)識(shí)為zhangsan.qq

以上已經(jīng)演示了API自帶的驗(yàn)證策略,以下稍微演示下自定義的驗(yàn)證策略。
自定義 AuthenticationStrategy 實(shí)現(xiàn)之前,首先簡(jiǎn)單看其 API:

//在所有Realm驗(yàn)證之前調(diào)用
AuthenticationInfo beforeAllAttempts(
Collection<? extends Realm> realms, AuthenticationToken token) 
throws AuthenticationException;
//在每個(gè)Realm之前調(diào)用
AuthenticationInfo beforeAttempt(
Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) 
throws AuthenticationException;
//在每個(gè)Realm之后調(diào)用
AuthenticationInfo afterAttempt(
Realm realm, AuthenticationToken token, 
AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t)
throws AuthenticationException;
//在所有Realm之后調(diào)用
AuthenticationInfo afterAllAttempts(
AuthenticationToken token, AuthenticationInfo aggregate) 
throws AuthenticationException;

5、自定義驗(yàn)證策略(com.luther.shiro.authenticationStrategy.LastSuccessfulStrategy)

/**
 * 驗(yàn)證所有realm,并返回最后一個(gè)驗(yàn)證通過(guò)的身份標(biāo)識(shí)
 * @author luther
 * @time 2019年7月5日  下午4:12:31
 */
public class LastSuccessfulStrategy extends AbstractAuthenticationStrategy {
	
	// 第一種方案修改afterAttempt方法
	@Override
	public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo,
			AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {
		return singleRealmInfo;
	}

//	// 第二種方案修改merge方法
//	@Override
//	protected AuthenticationInfo merge(AuthenticationInfo info, AuthenticationInfo aggregate) {
//		if (info != null) {
//			aggregate = info;
//		}
//		
//		return aggregate;
//	}
	
}

5.1 ini 配置文件 (shiro-lastSuccessfulStrategy.ini)

[main]
#指定securityManager的authenticator實(shí)現(xiàn),可以不指定,因?yàn)槠淠J(rèn)實(shí)現(xiàn)就是ModularRealmAuthenticator
#authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
#securityManager.authenticator=$authenticator

#指定securityManager.authenticator的authenticationStrategy為自定義的LastSuccessfulStrategy
authenticationStrategy=com.luther.shiro.authenticationStrategy.LastSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$authenticationStrategy

#聲明一個(gè)realm
myRealm1=com.luther.shiro.realm.MyRealm1
#聲明一個(gè)realm
myRealm2=com.luther.shiro.realm.MyRealm2
#聲明一個(gè)realm
myRealm3=com.luther.shiro.realm.MyRealm3
#指定securityManager的realms實(shí)現(xiàn),通過(guò) $name 來(lái)引入之前的 realm 定義
securityManager.realms=$myRealm3,$myRealm2,$myRealm1

5.2 測(cè)試代碼

/**
 * 演示自定義的LastSuccessfulStrategy的效果
 * 會(huì)對(duì)每個(gè)realm進(jìn)行驗(yàn)證,全部驗(yàn)證完后會(huì)返回驗(yàn)證成功的最后一個(gè)用戶標(biāo)識(shí)	
 * @author luther
 * @time 2019年7月5日  上午11:30:24
 */
@Test
public void testLastSuccessfulStrategy() {
	authentition("classpath:shiro-lastSuccessfulStrategy.ini", "zhangsan", "123");
}

5.3 測(cè)試結(jié)果

開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm3
com.luther.shiro.realm.MyRealm3 - 用戶zhangsan驗(yàn)證成功
開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm2
開(kāi)始驗(yàn)證com.luther.shiro.realm.MyRealm1
com.luther.shiro.realm.MyRealm1 - 用戶zhangsan驗(yàn)證成功
用戶zhangsan登錄成功,其身份標(biāo)識(shí)為zhangsan

上述就是小編為大家分享的什么是Shiro驗(yàn)證了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

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

AI