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

Spring Security如何優(yōu)雅的增加OAuth2協(xié)議授權模式

 更新時間:2020年09月04日 10:01:07   作者:zlt2000  
這篇文章主要介紹了Spring Security如何優(yōu)雅的增加OAuth2協(xié)議授權模式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、什么是OAuth2協(xié)議?

OAuth 2.0 是一個關于授權的開放的網(wǎng)絡協(xié)議,是目前最流行的授權機制。

數(shù)據(jù)的所有者告訴系統(tǒng),同意授權第三方應用進入系統(tǒng),獲取這些數(shù)據(jù)。系統(tǒng)從而產(chǎn)生一個短期的進入令牌(token),用來代替密碼,供第三方應用使用。

由于授權的場景眾多,OAuth 2.0 協(xié)議定義了獲取令牌的四種授權方式,分別是:

  • 授權碼模式:授權碼模式(authorization code)是功能最完整、流程最嚴密的授權模式。它的特點就是通過客戶端的后臺服務器,與"服務提供商"的認證服務器進行互動。
  • 簡化模式:簡化模式(implicit grant type)不通過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了"授權碼"這個步驟,因此得名。所有步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不需要認證。
  • 密碼模式:密碼模式(Resource Owner Password Credentials Grant)中,用戶向客戶端提供自己的用戶名和密碼??蛻舳耸褂眠@些信息,向"服務商提供商"索要授權。
  • 客戶端模式:客戶端模式(Client Credentials Grant)指客戶端以自己的名義,而不是以用戶的名義,向"服務提供商"進行認證。嚴格地說,客戶端模式并不屬于OAuth框架所要解決的問題。在這種模式中,用戶直接向客戶端注冊,客戶端以自己的名義要求"服務提供商"提供服務,其實不存在授權問題。

四種授權模式分別使用不同的 grant_type 來區(qū)分

二、為什么要自定義授權類型?

雖然 OAuth2 協(xié)議定義了4種標準的授權模式,但是在實際開發(fā)過程中還是遠遠滿足不了各種變態(tài)的業(yè)務場景,需要我們?nèi)U展。

例如增加圖形驗證碼、手機驗證碼、手機號密碼登錄等等的場景

而常見的做法都是通過增加 過濾器Filter 的方式來擴展 Spring Security 授權,但是這樣的實現(xiàn)方式有兩個問題:

  • 脫離了 OAuth2 的管理
  • 不靈活:例如系統(tǒng)使用 密碼模式 授權,網(wǎng)頁版需要增加圖形驗證碼校驗,但是手機端APP又不需要的情況下,使用增加 Filter 的方式去實現(xiàn)就比較麻煩了。

所以目前在 Spring Security 中比較優(yōu)雅和靈活的擴展方式就是通過自定義 grant_type 來增加授權模式。

三、實現(xiàn)思路

在擴展之前首先需要先了解 Spring Security 的整個授權流程,我以 密碼模式 為例去展開分析,如下圖所示

3.1. 流程分析

整個授權流程關鍵點分為以下兩個部分:

第一部分:關于授權類型 grant_type 的解析

  • 每種 grant_type 都會有一個對應的 TokenGranter 實現(xiàn)類。
  • 所有 TokenGranter 實現(xiàn)類都通過 CompositeTokenGranter 中的 tokenGranters 集合存起來。
  • 然后通過判斷 grantType 參數(shù)來定位具體使用那個 TokenGranter 實現(xiàn)類來處理授權。

 第二部分:關于授權登錄邏輯

  • 每種 授權方式 都會有一個對應的 AuthenticationProvider 實現(xiàn)類來實現(xiàn)。
  • 所有 AuthenticationProvider 實現(xiàn)類都通過 ProviderManager 中的 providers 集合存起來。
  • TokenGranter 類會 new 一個 AuthenticationToken 實現(xiàn)類,如 UsernamePasswordAuthenticationToken 傳給 ProviderManager 類。
  • ProviderManager 則通過 AuthenticationToken 來判斷具體使用那個 AuthenticationProvider 實現(xiàn)類來處理授權。

具體的登錄邏輯由 AuthenticationProvider 實現(xiàn)類來實現(xiàn),如 DaoAuthenticationProvider

 3.2. 擴展分析

根據(jù)上面的流程,擴展分為以下兩種場景

場景一:只對原有的授權邏輯進行增強或者擴展,如:用戶名密碼登錄前增加圖形驗證碼校驗。

該場景需要定義一個新的 grantType 類型,并新增對應的 TokenGranter 實現(xiàn)類 添加擴展內(nèi)容,然后加到 CompositeTokenGranter 中的 tokenGranters 集合里即可。

參考代碼:PwdImgCodeGranter.java

場景二:新加一種授權方式,如:手機號加密碼登錄。

該場景需要實現(xiàn)以下內(nèi)容:

  • 定義一個新的 grantType 類型,并新增對應的 TokenGranter 實現(xiàn)類添加到 CompositeTokenGranter 中的 tokenGranters 集合里
  • 新增一個 AuthenticationToken 實現(xiàn)類,用于存放該授權所需的信息。
  • 新增一個 AuthenticationProvider 實現(xiàn)類 實現(xiàn)授權的邏輯,并重寫 supports 方法綁定步驟二的 AuthenticationToken 實現(xiàn)類

參考代碼:MobilePwdGranter.java

 四、代碼實現(xiàn)

下面以 場景二 新增手機號加密碼授權方式為例,展示核心的代碼實現(xiàn)

4.1. 創(chuàng)建 AuthenticationToken 實現(xiàn)類

創(chuàng)建 MobileAuthenticationToken 類,用于存儲手機號和密碼信息

public class MobileAuthenticationToken extends AbstractAuthenticationToken {
	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

	private final Object principal;
	private Object credentials;

	public MobileAuthenticationToken(String mobile, String password) {
		super(null);
		this.principal = mobile;
		this.credentials = password;
		setAuthenticated(false);
	}

	public MobileAuthenticationToken(Object principal, Object credentials,
									 Collection<? extends GrantedAuthority> authorities) {
		super(authorities);
		this.principal = principal;
		this.credentials = credentials;
		super.setAuthenticated(true);
	}

	@Override
	public Object getCredentials() {
		return this.credentials;
	}

	@Override
	public Object getPrincipal() {
		return this.principal;
	}

	@Override
	public void setAuthenticated(boolean isAuthenticated) {
		if (isAuthenticated) {
			throw new IllegalArgumentException(
					"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
		}
		super.setAuthenticated(false);
	}

	@Override
	public void eraseCredentials() {
		super.eraseCredentials();
	}
}

4.2. 創(chuàng)建 AuthenticationProvider 實現(xiàn)類

創(chuàng)建 MobileAuthenticationProvider 類,實現(xiàn)登錄邏輯,并綁定 MobileAuthenticationToken

@Setter
public class MobileAuthenticationProvider implements AuthenticationProvider {
  private ZltUserDetailsService userDetailsService;
  private PasswordEncoder passwordEncoder;

  @Override
  public Authentication authenticate(Authentication authentication) {
    MobileAuthenticationToken authenticationToken = (MobileAuthenticationToken) authentication;
    String mobile = (String) authenticationToken.getPrincipal();
    String password = (String) authenticationToken.getCredentials();
    UserDetails user = userDetailsService.loadUserByMobile(mobile);
    if (user == null) {
      throw new InternalAuthenticationServiceException("手機號或密碼錯誤");
    }
    if (!passwordEncoder.matches(password, user.getPassword())) {
      throw new BadCredentialsException("手機號或密碼錯誤");
    }
    MobileAuthenticationToken authenticationResult = new MobileAuthenticationToken(user, password, user.getAuthorities());
    authenticationResult.setDetails(authenticationToken.getDetails());
    return authenticationResult;
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return MobileAuthenticationToken.class.isAssignableFrom(authentication);
  }
}

4.3. 創(chuàng)建 TokenGranter 實現(xiàn)類

創(chuàng)建 MobilePwdGranter 類并定義 grant_type 的值為 mobile_password

public class MobilePwdGranter extends AbstractTokenGranter {
  private static final String GRANT_TYPE = "mobile_password";

  private final AuthenticationManager authenticationManager;

  public MobilePwdGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices
      , ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
    super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
    this.authenticationManager = authenticationManager;
  }

  @Override
  protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
    Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
    String mobile = parameters.get("mobile");
    String password = parameters.get("password");
    parameters.remove("password");

    Authentication userAuth = new MobileAuthenticationToken(mobile, password);
    ((AbstractAuthenticationToken) userAuth).setDetails(parameters);
    userAuth = authenticationManager.authenticate(userAuth);
    if (userAuth == null || !userAuth.isAuthenticated()) {
      throw new InvalidGrantException("Could not authenticate mobile: " + mobile);
    }

    OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
    return new OAuth2Authentication(storedOAuth2Request, userAuth);
  }
}

4.4. 加到 CompositeTokenGranter 中的集合里

// 添加手機號加密碼授權模式
tokenGranters.add(new MobilePwdGranter(authenticationManager, tokenServices, clientDetailsService, requestFactory));

4.5. 測試

使用以下地址,指定 grant_typemobile_password 進行授權獲取 access_token

/oauth/token?grant_type=mobile_password&mobile={mobile}&password={password}

五、參考樣例

詳細的代碼實現(xiàn)可以參考

https://gitee.com/zlt2000/microservices-platform/tree/master/zlt-uaa

到此這篇關于Spring Security如何優(yōu)雅的增加OAuth2協(xié)議授權模式的文章就介紹到這了,更多相關Spring Security OAuth2內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 23種設計模式(15)java解釋器模式

    23種設計模式(15)java解釋器模式

    這篇文章主要為大家詳細介紹了23種設計模式之java解釋器模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • java實現(xiàn)文件上傳功能

    java實現(xiàn)文件上傳功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)文件上傳功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Spring Retry重試框架的使用講解

    Spring Retry重試框架的使用講解

    重試的使用場景比較多,比如調(diào)用遠程服務時,由于網(wǎng)絡或者服務端響應慢導致調(diào)用超時,此時可以多重試幾次。用定時任務也可以實現(xiàn)重試的效果,但比較麻煩,用Spring Retry的話一個注解搞定所有,感興趣的可以了解一下
    2023-01-01
  • Spring Boot使用Redisson實現(xiàn)滑動窗口限流的項目實踐

    Spring Boot使用Redisson實現(xiàn)滑動窗口限流的項目實踐

    滑動窗口限流是一種流量控制策略,用于控制在一定時間內(nèi)的請求頻率,本文主要介紹了Spring Boot使用Redisson實現(xiàn)滑動窗口限流的項目實踐,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Java的Tomcat和Servlet的運行原理詳解

    Java的Tomcat和Servlet的運行原理詳解

    這篇文章主要為大家詳細介紹了Java的Tomcat和Servlet,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Java8中的Stream流式操作教程之王者歸來

    Java8中的Stream流式操作教程之王者歸來

    這篇文章主要給大家介紹了關于Java8中Stream流式操作的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java8具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-09-09
  • Spring框架應用的權限控制系統(tǒng)詳解

    Spring框架應用的權限控制系統(tǒng)詳解

    在本篇文章里小編給大家整理的是關于基于Spring框架應用的權限控制系統(tǒng)的研究和實現(xiàn),需要的朋友們可以學習下。
    2019-08-08
  • IDEA 使用mybatis插件Free Mybatis plugin的步驟(推薦)

    IDEA 使用mybatis插件Free Mybatis plugin的步驟(推薦)

    這篇文章主要介紹了IDEA 使用mybatis插件Free Mybatis plugin的相關知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Java實現(xiàn)SSL雙向認證的方法

    Java實現(xiàn)SSL雙向認證的方法

    這篇文章主要介紹了Java實現(xiàn)SSL雙向認證的方法,實例分析了ssl認證的原理與相關實現(xiàn)技巧,需要的朋友可以參考下
    2016-08-08
  • Java稀疏數(shù)組的應用實踐

    Java稀疏數(shù)組的應用實踐

    本文主要介紹了Java稀疏數(shù)組的應用實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06

最新評論

九龙城区| 台东市| 浮山县| 祁连县| 江永县| 鲁山县| 镇坪县| 华安县| 光泽县| 桐梓县| 海丰县| 白朗县| 扎鲁特旗| 周至县| 西昌市| 安溪县| 五华县| 武乡县| 洱源县| 达州市| 微博| 马尔康县| 湛江市| 平利县| 军事| 杨浦区| 宾川县| 成安县| 广水市| 堆龙德庆县| 永安市| 平和县| 绩溪县| 玉门市| 邯郸市| 神池县| 上虞市| 卢湾区| 茂名市| 杭锦旗| 横山县|