SpringCloudOAuth2--概述

什麼是OAuth2

0Auth2是一個標準的授權協議。OAuth2 取代了在2006年創建的OAuth1 的工作,OAuth2對OAuth1沒有做兼容,即完全廢棄了0Auth1。0Auth2 允許不同的客戶端通過認證和授權的形式來訪問被其保護起來的資源。在認證和授權的過程中,主要包含以下3種角色。

  • 服務提供方Authorization Server
  • 資源持有者Resource Server
  • 客戶端Client

OAuth2的認證流程圖如下:
在這裏插入圖片描述

  1. 用戶(資源持有者)打開客戶端,客戶端 客戶端詢問用戶授權。
  2. 用戶同意授權。
  3. 客戶端向授權服務器申請授權。
  4. 授權服務器對客戶端進行認證,也包括用戶信息的認證,認證成功後授權給予令牌。
  5. 客戶端獲取令牌後,攜帶令牌向資源服務器請求資源
  6. 資源服務器確認令牌正確無誤,向客戶端釋放資源。

如何使用Spring OAuth2

OAuth2協議在Spring Resources中的實現爲Spring OAuth2。Spring OAuth2分爲兩部分,分別是OAuth2 Provider和OAuth2 Client,下 面來對二者逐一講解。

一. OAuth Provider:

OAuth2Provider負責公開被OAuth2保護起來的資源。OAuth2Provider需要配置代表用戶的OAuth2客戶端信息,被用戶允許的客戶端就可以訪問被OAuth2保護的資源。
OAuth2Provider通過管理和驗證0Auth2令牌來控制客戶端是否有權限訪問被其保護的資源。另外,Oauth2 Provider 還必須爲用戶提供認證API接口。根據認證API接口,用戶提供賬號和密碼等信息,來確認客戶端是否可以被0Auth2 Provider 授權。這樣做的好處就是第三方客戶端不需要獲取用戶的賬號和密碼,通過授權的方式就可以訪問被OAuth2保護起來的資源。

OAuth2 Provider的角色被分爲Authorization Service (授權服務)和Resource Service (資源服務),通常它們不在同一個服務中,可能一個Authorization Service 對應多個ResourceService。Spring OAuth2需配合Spring Security一起使用,所有的請求由Spring MVC控制器處理,並經過一系列的Spring Security過濾器。

在Spring Security過濾器鏈中有以下兩個節點,這兩個節點是向Authorization Service獲取驗證和授權的:

  • 授權節點:默認爲/oauth/authorize
  • 獲取Token節點:默認爲/oauth/token

1. Authorization Server配置:

在配置Authorization Server 時,需要考慮客戶端(Client) 從用戶獲取訪問令牌的授權類型(例如授權代碼、用戶憑據、刷新令牌)。Authorization Server需要配置客戶端的詳細信息和令牌服務的實現。

在任何實現了AuthorizationServerConfigurer 接口的類上加@EnableAuthorizationServer註解,開啓Authorization Server 的功能,以Bean的形式注入Spring IoC容器中,並需要實現以下3個配置:

  • ClientDetailsServiceConfigurer:配置客戶端信息
  • AuthorizationServerEndpointsConfigurer:配置授權Token的節點和Token服務
  • AuthorizationServerSecurityConfigurer:配置Token節點的安全策略

ClientDetailsServiceConfigurer:

客戶端的配置信息既可以放在內存中,也可以放在數據庫中,需要配置以下信息:

  • clientId:客戶端Id,需要在Authorization Server中是唯一的;
  • secret:客戶端的密碼;
  • scope:客戶端的域;
  • authorizedGrantTypes:認證類型;
  • authorities:權限信息;

客戶端信息可以存儲在數據庫中,這樣就可以通過更改數據庫來實時更新客戶端信息的數據。Spring OAuth2已經設計好了數據庫的表,且不可變。創建數據庫的腳本如下:

create table oauth_client_details (
  client_id VARCHAR(128) PRIMARY KEY,
  resource_ids VARCHAR(128),
  client_secret VARCHAR(128),
  scope VARCHAR(128),
  authorized_grant_types VARCHAR(128),
  web_server_redirect_uri VARCHAR(128),
  authorities VARCHAR(128),
  access_token_validity INTEGER,
  refresh_token_validity INTEGER,
  additional_information VARCHAR(4096),
  autoapprove VARCHAR(128)
);

create table oauth_client_token (
  token_id VARCHAR(128),
  token BLOB,
  authentication_id VARCHAR(128) PRIMARY KEY,
  user_name VARCHAR(128),
  client_id VARCHAR(128)
);

create table oauth_access_token (
  token_id VARCHAR(128),
  token BLOB,
  authentication_id VARCHAR(128) PRIMARY KEY,
  user_name VARCHAR(128),
  client_id VARCHAR(128),
  authentication BLOB,
  refresh_token VARCHAR(128)
);

create table oauth_refresh_token (
  token_id VARCHAR(128),
  token BLOB,
  authentication BLOB
);

create table oauth_code (
  code VARCHAR(128), authentication BLOB
);

create table oauth_approvals (
    userId VARCHAR(128),
    clientId VARCHAR(128),
    scope VARCHAR(128),
    status VARCHAR(10),
    expiresAt TIMESTAMP,
    lastModifiedAt TIMESTAMP
);


-- customized oauth_client_details table
create table ClientDetails (
  appId VARCHAR(128) PRIMARY KEY,
  resourceIds VARCHAR(128),
  appSecret VARCHAR(128),
  scope VARCHAR(128),
  grantTypes VARCHAR(128),
  redirectUrl VARCHAR(128),
  authorities VARCHAR(128),
  access_token_validity INTEGER,
  refresh_token_validity INTEGER,
  additionalInformation VARCHAR(4096),
  autoApproveScopes VARCHAR(128)
);

AuthorizationServerEndpointsConfigurer:

在默認情況下,AuthorizationServerEndpointsConfigurer配置開啓了所有的驗證類型,除了密碼類型的驗證,密碼驗證只有配置了authenticationManager的配置纔會開啓。AuthorizationServerEndpointsConfigurer配置由以下5項組成:

  • authenticationManager:只有配置了該選項,密碼認證纔會開啓。在大多數情況下都是密碼驗證,所以一般都會配置這個選項。
  • userDetailsService:配置獲取用戶認證信息的接口。
  • authorizationCodeServices:配置驗證碼服務。
  • implicitFrantService:配置管理implict驗證的狀態。
  • tokenGranter:配置Token Granter。

另外,需要設置Token的管理策略,目前支持以下3種:

  • InMemoryTokenStore:Token存儲在內存中;
  • JdbcTokenStore:Token存儲在數據庫中。需要引入spring-jdbc的依賴包,並配置數據源,以及初始化Spring OAuth2的數據庫腳本;
  • JwtTokenStore:採用JWT形式,這種形式沒有做任何的存儲,因爲JWT本身包含了用戶驗證的所有信息,不需要存儲。採用這種形式,需要引入spring-jwt的依賴;

QuthorizationServerSecurityConfigurer:

如果資源服務和授權服務是在同一個服務中,用默認的配置即可,不需要做其他任何的配置。但是如果資源服務和授權服務不在同一個服務中,則需要做一些額外配置。如果採用RemoteTokenServices ( 遠程Token校驗),資源服務器的每次請求所攜帶的Token都需要從授權服務做校驗。這時需要配置“/oauth/check_ token" 校驗節點的校驗策略。

Authorization Server的配置比較複雜,細節較多,Authorization Server的配置思維導圖如圖所示。

通過在實現了AuthorizationServerConfigurer 接口的類上加@EnableAuthorizationServer註解,開啓AuthorizationServer的功能,並注入IoC容器中。然後需要配置ClientDetailsServiceConfigurer、AuthorizationServerSecurityConfigurer和AuthorizationServerEndpointsConfigurer,它們有很多可選的配置,需要慢慢理解。

在這裏插入圖片描述

2. Resource Server的配置:

Resource Server ( 可以是授權服務器,也可以是其他的資源服務)提供了受OAuth2保護的資源,這些資源爲API接口、Html頁面、Js文件等。

Spring OAuth2 提供了實現此保護功能的Spring Security 認證過濾器。在加了@Configuration註解的配置類上加@EnableResourceServer註解,開啓Resource Server的功能,並使用ResourceServerConfigurer進行配置( 如有必要),需要配置以下的內容:

  • tokenServices: 定義Token Service。例如用ResourceServerTokenservices 類,配置Token
    是如何編碼和解碼的。如果Resource Server和Authorization Server在同一個工程上,則不需要配置tokenServices, 如果不在同一個程序就需要配置。也可以用RemoteTokenServices類,即Resource Server 採用遠程授權服務器進行Token解碼,這時也不需要配置此選項,本章案例採用此方式。
  • resourceld:配置資源Id。

二. OAuth2 Client:

OAuth2 Client (客戶端)用於訪問被OAuth2保護起來的資源。客戶端需要提供用於存儲用戶的授權碼和訪問令牌的機制,需要配置如下兩個選項:

  • Protected Resource Configuration(受保護資源配置)
  • Client Configuration(客戶端配置)

1. Protected Resource Configuration:

使用OAuth2ProtectedResourceDetails類型的Bean來定義受保護的資源,受保護的資源具有以下屬性:

  • Id:資源的ID,它在Spring OAuth2協議中沒有用到,用於客戶端尋找資源,不需要做配置,默認即可;
  • clientId:OAuth2 Client的Id,和之前OAuth2 Provider中的一一對應;
  • clientSecret:客戶端密碼,和之前OAuth2 Provider中配置的一一對應;
  • accessTokenUri:獲取Token的API節點;
  • scope:客戶端的域;
  • clientAuthenticationScheme:有兩種客戶端驗證類型,分別爲Http Basic 和 Form,默認爲Http Basic;
  • userAuthorizationUri:如果用戶需要授權訪問資源,則用戶將被重定向到認證Url;

2. Client Configuration:

對於OAuth2 Client的配置,可以使用@EnableOAuth2Client註解來簡化配置,另外還需要配置以下兩項:

  • 創建一個過濾器Bean(Bean的Id爲oauth2ClientContextFilter),用來存儲當前請求和上下文的請求。在請求期間,如果用戶需要進行身份驗證,則用戶會被重定向到OAuth2的認證Url;
  • 在Request域內創建AccessTokenRequest類型的Bean;

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章