Spring セキュリティ + Oauth2 認証ソリューション: プロジェクトの構成とテスト

このプロジェクトでは、Spring セキュリティ + Oauth2 を使用して、ユーザー認証とユーザー認可を完了します。Spring セキュリティは、強力で高度にカスタマイズ可能な認証およびアクセス制御フレームワークです。Spring セキュリティ フレームワークは、Oauth2
プロトコルを統合します。次の図は、プロジェクトの認証アーキテクチャ図です。

1. ユーザーは認証サービスに認証を要求します。
2. 認証サービスはユーザーの ID トークンを発行します。ID トークンがあるということは、その ID が正当であることを示します。
3. ユーザーは、リソース サービスを要求するためにトークンを保持します。リソース サービスの要求は、まずゲートウェイを通過する必要があります。
4. ゲートウェイはユーザーの ID トークンの有効性を検証します。有効でない場合は、ユーザーがログインしていないことを意味します。有効な場合、ユーザーはアクセスを続行できます。
5. リソース サービスはトークンを取得し、トークンに基づいて承認を完了します。
6. 認可完了後、リソースサービスはリソース情報を応答します。

Oauth2認証コードモード

Oauth2認証モード

Oauth2には、認可
コードモード(Authorization Code)、
暗黙的認可モード(Implicit)、
パスワードモード(Resource Owner Password Credentials)、
クライアントモード(Client Credentials)の認可モードがあり
、その中で認可コードモードとパスワードモードが広く使われています。このセクションでは、認証コード モードについて説明します。

認可コード認可プロセス

上記の Dark Horse Programmer Web サイトで WeChat 認証を使用するプロセスは認可コード モードであり、そのプロセスは次のとおりです。 1. クライアントが
サードパーティの認可を要求します。
2. ユーザー (リソース所有者) がクライアントの認可に同意します。
3.クライアントは認可コードを取得し、認証サーバーにトークンの申請を要求します
4. 認証サーバーはクライアントにトークンで応答します
5. クライアントはリソース サーバーにリソースを要求し、リソース サービスはトークンの有効性を検証します
6. リソースサーバーは保護されたリソースを返します

認証コードを申請する

認証サービスに認証コードを取得するよう要求します:
Get request:

curl localhost:40400/auth/oauth/authorize?client_id=XcWebApp&response_type=code&scop=app&redirect_uri=http://localhost

パラメータのリストは次のとおりです。

  • client_id: クライアント ID。認可設定クラスで設定されたクライアント ID と一致します。
  • response_type: 認可コードモードはコードに固定されています
  • scop: クライアント スコープ。認可設定クラスで設定された scop と一致します。
  • redirect_uri: リダイレクトURI、認可コード適用が成功するとこのアドレスにジャンプし、その後ろにcodeパラメータ(認可コード)が付加されます。
    まずログインページに移動します。

ここに画像の説明を挿入

アカウントとパスワードを入力し、「ログイン」をクリックします。
Spring Security はリクエストを受信すると、UserDetailsS​​ervice インターフェースのloadUserByUsername メソッドを呼び出して、ユーザーの正しいパスワードを照会します。
現在インポートされている基本プロジェクトには正しいパスワードが「123」とハードコードされているので、ここにアカウント番号を入力し、パスワードとして123を入力すると認証が通ります。
次に、認証ページに入ります。
ここに画像の説明を挿入

「同意する」をクリックします。
次に、認証コードを返します。
認証サービスは認証コードを伝え、リダイレクトにジャンプします。
ここに画像の説明を挿入

トークンを申請する

認可コードを取得後、トークンを申請します。
リクエスト後のhttp://localhost:40400/auth/oauth/token
パラメータは次のとおりです。

  • Grant_type: 認可タイプ。認可コードモードを示す authorization_code を入力します。
  • code: 認証コード、先ほど取得した認証コードです 注: 認証コードは一度使用すると無効になるため、再度申請する必要があります。
  • redirect_uri: 認可コード申請時のリダイレクトURLは、認可コード申請時のredirect_uriと一致している必要があります。
    このリンクでは http Basic 認証を使用する必要があります。
    http 基本認証とは何ですか?
    httpプロトコルで定義されている認証方式で、クライアントIDとクライアントパスワードを「クライアントID:クライアントパスワード」の形式で結合し、base64でエンコードしてヘッダーに配置してサーバーに要求します。
    :
    基本 WGNXZWJBcHA6WGNXZWJBcHA=WGNXZWJBcHA6WGNXZWJBcHA=ユーザー名: パスワードの Base64 エンコード。
    認証が失敗し、サーバーは 401 Unauthorized を返します。
    上記のテストは postman を使用して完了します:
    http 基本認証:
    ここに画像の説明を挿入
    クライアント ID とクライアント パスワードは、データベース oauthclientdetails テーブル内のクライアント ID とクライアント パスワードと一致します。
    Post request パラメータ:
    ここに画像の説明を挿入
    クリックして送信:
    トークンの申請が成功:
    ここに画像の説明を挿入
    access_token: アクセス トークン、リソースにアクセスするためにこのトークンを運ぶ
    token_type: MAC トークンとベアラー トークンの 2 種類があり、両者の検証アルゴリズムは異なります。RFC 6750 では、Oauth2 を推奨しています。ベアラー トークン (http://www.rfcreader.com/#rfc6750) を使用します。
    refresh_token: リフレッシュ トークン。このトークンを使用して、アクセス トークンの有効期限を延長します。
    expires_in: 有効期限 (秒単位)。
    scope: スコープ。定義されたクライアント スコープと一致します。

リソースサービスの認可

リソース サービスの承認プロセス
リソース サービスには、アクセスできる保護されたリソースがあります。クライアントは、リソース サービスにアクセスするためのトークンを保持します。トークンが正当であれば、次の図に示すように、リソース サービス内のリソースに正常にアクセスできます。
ここに画像の説明を挿入

上図のビジネス プロセスは次のとおりです:
1. クライアントが認証サービスにトークンの申請を要求します
2. 認証サービスがトークンを生成します
認証サービスは非対称暗号化アルゴリズムを使用し、秘密キーを使用してトークンを生成しますトークン。
3. クライアントは、リソース サービスにアクセスするためのトークンを運び、
HTTP ヘッダーに「Authorization: Bearer token」を追加します。
4. リソース サービスは認証サービスにトークンの有効性の検証を要求し、
リソース サービスはトークンを受け取り、公開キーを使用してトークンの有効性を検証します。
5. トークンは有効であり、リソース サービスはクライアントにリソース情報を応答します。

リソースサービスの認可設定
基本的にすべてのマイクロサービスはリソースサービスです. ここではコース管理サービスの認可制御を設定します. 認可制御の設定後, コース情報にアクセスしたい場合は, トークンを提供する必要があります.
1. 公開キーを構成する
認証サービスは非対称暗号化アルゴリズムを使用してトークンを生成し、認証サービスは秘密キー暗号化を使用してトークンを生成し、公開キーをリソース サービスに提供し、リソース サービスは公開キーを使用して正当性を検証します。トークンの。
公開キーを publickey.txt ファイルにコピーし、このファイルをリソース サービス プロジェクトのクラスパスにコピーします。
ここに画像の説明を挿入

2. 依存関係を追加する

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring‐cloud‐starter‐oauth2</artifactId>
</dependency>

3. config パッケージの下に ResourceServerConfig クラスを作成します。

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)//激活方法上的
PreAuthorize注解
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
    
	//公钥
	private static final String PUBLICKEY = "publickey.txt";
	//定义JwtTokenStore,使用jwt令牌
	@Bean
	public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
    
    
		return new JwtTokenStore(jwtAccessTokenConverter);
	}
	//定义JJwtAccessTokenConverter,使用jwt令牌
	@Bean
	public JwtAccessTokenConverter jwtAccessTokenConverter() {
    
    
		JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
		converter.setVerifierKey(getPubKey());
		return converter;
	}
	/**
	* 获取非对称加密公钥 Key
	* @return 公钥 Key
	*/
	private String getPubKey() {
    
    
		Resource resource = new ClassPathResource(PUBLIC_KEY);
		try {
    
    
			InputStreamReader inputStreamReader = new
			InputStreamReader(resource.getInputStream());
			BufferedReader br = new BufferedReader(inputStreamReader);
			return br.lines().collect(Collectors.joining("\n"));
		} catch (IOException ioe) {
    
    
			return null;
		}
	}
	//Http安全配置,对每个到达系统的http请求链接进行校验
	@Override
	public void configure(HttpSecurity http) throws Exception {
    
    
		//所有请求必须认证通过
		http.authorizeRequests().anyRequest().authenticated();
	}
}

リソースサービス認可テスト

ここではコース画像クエリをテストします

get http://localhost:31200/course/coursepic/list/4028e58161bd3b380161bd3bcd2f0000

リクエストにトークンが含まれていない場合は、エラーが報告されます。

{
    
    
	"error": "unauthorized",
	"error_description": "Full authentication is required to access this resource"
}

リクエスト時にトークンを運ぶ:
http ヘッダーに認可を追加: ベアラー トークン
ここに画像の説明を挿入

間違ったトークンを入力すると、リソースに正常にアクセスできなくなります。

ここに画像の説明を挿入

swagger-ui にアクセスできない問題を解決する

コース管理者が認可を追加してから swagger-ui にアクセスすると、エラーが報告されます:
ここに画像の説明を挿入
認可設定クラス ResourceServerConfig の configure メソッドを変更します:
swagger-ui のリクエスト パスを解放します:

//Http安全配置,对每个到达系统的http请求链接进行校验
@Override
public void configure(HttpSecurity http) throws Exception {
    
    
	//所有请求必须认证通过
	http.authorizeRequests()
	//下边的路径放行
	.antMatchers("/v2/api‐docs", "/swagger‐resources/configuration/ui",
	"/swagger‐resources","/swagger‐resources/configuration/security",
	"/swagger‐ui.html","/webjars/**").permitAll()
	.anyRequest().authenticated();
}

注:
上記の構成を通じて swagger-ui にアクセスできますが、認証構成が削除されるか、すべての
リクエストが許可される (「/**」) が上記の構成に追加されない限り、単体テストを実行することはできません。

おすすめ

転載: blog.csdn.net/a772304419/article/details/132084122