最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springSecurity之AuthenticationProvider用法解析

 更新時(shí)間:2023年03月17日 14:34:25   作者:chihaihai  
這篇文章主要介紹了springSecurity之AuthenticationProvider用法解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

AuthenticationProvider解析

首先進(jìn)入到AuthenticationProvider源碼中可以看到它只是個(gè)簡(jiǎn)單的接口里面也只有兩個(gè)方法:

public interface AuthenticationProvider {
	// 具體認(rèn)證流程
	Authentication authenticate(Authentication authentication)
			throws AuthenticationException;	
    // supports函數(shù)用來(lái)指明該P(yáng)rovider是否適用于該類(lèi)型的認(rèn)證,如果不合適,則尋找另一個(gè)Provider進(jìn)行驗(yàn)證處理。	
	boolean supports(Class<?> authentication);
}

AuthenticationProvider是用戶自定義身份認(rèn)證,認(rèn)證流程頂級(jí)接口。

唯一作用即使用來(lái)進(jìn)行身份驗(yàn)證,同時(shí)springSecurity也為我們提供了很多方便的實(shí)現(xiàn)類(lèi)。

在這里插入圖片描述

當(dāng)我們沒(méi)有指定相關(guān)AuthenticationProvider 對(duì)象時(shí)springSecurity默認(rèn)使用的就時(shí)上圖中的DaoAuthenticationProvider進(jìn)行驗(yàn)證。

也就是最常見(jiàn)的賬戶名密碼的方式。但是實(shí)際開(kāi)發(fā)中我們往往需要實(shí)現(xiàn)自定義認(rèn)證流程比如最常見(jiàn)的短信驗(yàn)證碼,第三方登錄等等。

這個(gè)時(shí)候我們就可以通過(guò)實(shí)現(xiàn)自己的 AuthenticationProvider方式來(lái)進(jìn)行自定義認(rèn)證。

只需要在WebSecurityConfigurerAdapter適配器類(lèi)的config方法中加入自己實(shí)現(xiàn)的AuthenticationProvider 即可。

 @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider());
    }

說(shuō)到AuthenticationProvider就離不開(kāi)AuthenticationManager這個(gè)接口

public interface AuthenticationManager {
	Authentication authenticate(Authentication authentication)
			throws AuthenticationException;
}

同樣的AuthenticationManager也是一個(gè)頂級(jí)接口,可以看到它其中也定義了一個(gè)跟AuthenticationProvider一摸一樣的方法。

如果說(shuō)Auth ntic ationProvider是對(duì)認(rèn)證的具體實(shí)現(xiàn),則AuthenticationManager則是對(duì)我們眾多AuthenticationProvider的一個(gè)統(tǒng)一管理。

Authentication Ma nager的實(shí)現(xiàn)有很多,通常使用ProviderManager對(duì)認(rèn)證請(qǐng)求鏈進(jìn)行管理。

在這里插入圖片描述

從源碼中可以看到

ProviderManager提供了一個(gè)list對(duì)AuthenticationProvider進(jìn)行統(tǒng)一管理,即一個(gè)認(rèn)證處理器鏈來(lái)支持同一個(gè)應(yīng)用中的多個(gè)不同身份認(rèn)證機(jī)制,ProviderManager將會(huì)根據(jù)順序來(lái)進(jìn)行驗(yàn)證。

public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		Class<? extends Authentication> toTest = authentication.getClass();
		AuthenticationException lastException = null;
		AuthenticationException parentException = null;
		Authentication result = null;
		Authentication parentResult = null;
		boolean debug = logger.isDebugEnabled();

		for (AuthenticationProvider provider : getProviders()) {
			// 如果支持認(rèn)證實(shí)現(xiàn)類(lèi)就繼續(xù)處理
			if (!provider.supports(toTest)) {
				continue;
			}

			if (debug) {
				logger.debug("Authentication attempt using "
						+ provider.getClass().getName());
			}

			try {
			  // 調(diào)用實(shí)現(xiàn)類(lèi)的authenticate方法進(jìn)行真實(shí)業(yè)務(wù)邏輯認(rèn)證處理
				result = provider.authenticate(authentication);

				if (result != null) {
					copyDetails(authentication, result);
					break;
				}
			}
			catch (AccountStatusException e) {
				prepareException(e, authentication);
				// SEC-546: Avoid polling additional providers if auth failure is due to
				// invalid account status
				throw e;
			}
			catch (InternalAuthenticationServiceException e) {
				prepareException(e, authentication);
				throw e;
			}
			catch (AuthenticationException e) {
				lastException = e;
			}
		}

		if (result == null && parent != null) {
			// Allow the parent to try.
			try {
				result = parentResult = parent.authenticate(authentication);
			}
			catch (ProviderNotFoundException e) {
				// ignore as we will throw below if no other exception occurred prior to
				// calling parent and the parent
				// may throw ProviderNotFound even though a provider in the child already
				// handled the request
			}
			catch (AuthenticationException e) {
				lastException = parentException = e;
			}
		}

		if (result != null) {
			if (eraseCredentialsAfterAuthentication
					&& (result instanceof CredentialsContainer)) {
				// Authentication is complete. Remove credentials and other secret data
				// from authentication
				((CredentialsContainer) result).eraseCredentials();
			}

			// If the parent AuthenticationManager was attempted and successful than it will publish an AuthenticationSuccessEvent
			// This check prevents a duplicate AuthenticationSuccessEvent if the parent AuthenticationManager already published it
			if (parentResult == null) {
			  //  //發(fā)送認(rèn)證成功事件
				eventPublisher.publishAuthenticationSuccess(result);
			}
			return result;
		}

		// Parent was null, or didn't authenticate (or throw an exception).

		if (lastException == null) {
			lastException = new ProviderNotFoundException(messages.getMessage(
					"ProviderManager.providerNotFound",
					new Object[] { toTest.getName() },
					"No AuthenticationProvider found for {0}"));
		}

		// If the parent AuthenticationManager was attempted and failed than it will publish an AbstractAuthenticationFailureEvent
		// This check prevents a duplicate AbstractAuthenticationFailureEvent if the parent AuthenticationManager already published it
		if (parentException == null) {
			prepareException(lastException, authentication);
		}

		throw lastException;
	}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

博客| 吉木乃县| 东光县| 无为县| 贡嘎县| 曲阜市| 剑川县| 锡林郭勒盟| 武穴市| 蕉岭县| 昔阳县| 曲麻莱县| 晋中市| 仲巴县| 合肥市| 光泽县| 虎林市| 新田县| 长子县| 余江县| 长沙县| 大埔县| 阳朔县| 习水县| 晋中市| 灵璧县| 无锡市| 松阳县| 刚察县| 彰化县| 连云港市| 娱乐| 大英县| 若尔盖县| 大同市| 陇西县| 报价| 昌都县| 高碑店市| 原阳县| 永吉县|