[MSA]認証システム開発者(3)-API間の通信と構成サーバ
39192 ワード
1.API間の通信
前回の記事では、gatewayとeurekaを介してmsaサービスを構築する方法について説明しました.
でも開発が終わってから問題が発生しました
ドメインごとにサーバを分割してユーザデータを表示するには、Authサーバが重複するEntityを作成し、DBにアクセスする必要があります.このやり方はmsaの原則に違反するだけでなく,重複するコードを増加させる.したがって、Authサーバは、ログインしようとするユーザの情報を受信するために、ユーザサーバに要求を送信しなければならない.
従って、マイクロサービスは、機能を実行するために適切なデータをユーザに配信するために、各マイクロサービスインスタンスが有機的にインタラクションする方法を採用する.
サーバ間の通信方法は、主に次のとおりです.
同期:Rest Template、Feign Client(HTTP)/g Rpc
非同期:Kafka、Amazon SQL(AMPプロトコル)などのMessage Agent
本プロジェクトでは、Spring Cloud Feign ClientというREST apiを使用します.
1.1. Feign Client接続
Authサーバへの依存性を追加し、
@EnableFeignClients
の操作説明を追加します.build.gradle
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
UserApplication.java@EnableFeignClients
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
1.2. インタフェースの作成とサービスコール
Http Endpointからデータを受信するインタフェースを作成します.Eurekaに登録されているInstance名をFeignClientオペレーティングシステムに追加すると、自動的にマッピングされます.
UserFeignClient.java
@FeignClient(name = "AUTH-USER-SERVER")
public interface UserFeignClient {
@PostMapping("/email")
UserResponseDto getUser(@RequestParam String email);
}
サービスがクライアントを呼び出すと、要求がユーザー・サーバ上の対応するエンドポイントに送信され、データが受信されます.AuthService.java
@Service
@RequiredArgsConstructor
public class AuthenticationService {
...
private final UserServiceClient userServiceClient;
@Transactional
public TokenDto loginUsers(AuthenticationRequestDto dto) {
UserResponseDto user = userServiceClient.getUser(dto.getEmail());
String salt = user.getSalt();
String password = saltUtil.encodePassword(salt,dto.getPassword());
if(!user.getPassword().equals(password)){
throw new BadRequestException(ExceptionType.INCORRECT_PASSWORD);
}
TokenDto tokenDto = jwtTokenProvider.generateToken(user);
redisUtil.setDataExpire(user.getName(),tokenDto.getRefreshToken(), 60 * 30L);
return tokenDto;
}
}
2.サーバー配置の構成
2.1. Spring Cloud Config
各マイクロサービスには、上記のJWTトークンまたはDataBase設定のような繰り返しの設定があります.
Spring Cloud Configサーバは、これらのシステムの優先パラメータを集中させ、変更をリアルタイムで適用できます.したがって、変更を行う場合は、毎日
수정-빌드-재배포
の負担を負う必要はありません.また、パスワードや秘密鍵などの機密情報がサービス項目から露出しないため、セキュリティ面でも改善される.
コンフィギュレーションサーバで使用される設定ファイルを管理するには、ローカルファイル、Gitリポジトリなど、さまざまな方法がありますが、Spring ConfigではGitの使用を推奨しているため、この方法を採用しています.
2.2. Git Repositoryの作成
まずgithubにアクセスしてリモートレジストリを作成し、環境固有の設定ファイルを作成します.
yamlファイルの名前は
${ApplicationName}-${EnvironmentName}.yml
に設定する必要があります.この名前に基づいて、http://CONFIG-SERVER/{ApplipcationName}/{EnvironmentName}に後でアクセスします.
# application.yml (필수X)
default:
owner: config-service's git folder
content: properties for msa project
# user-service.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/ncns_db
username: username
password: password
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
use_sql_comments: true
format_sql: true
show_sql: true
hibernate:
ddl-auto: update
generate-ddl: true
token:
key: tokenkey
default:
message: user-service default properties
# user-service-test.yml
spring:
datasource:
url: jdbc:h2:mem:testdb
username: sa
password:
driverClassName: org.h2.Driver
jpa:
show_sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
token:
key: tokenkey
default:
message: user-service test profiles
2.3. Spring Cloud Configプロジェクトの作成
スプリングアイテムを作成して、次の依存項目と
@EnableConfigServer
アクションを追加します.build.gradle
implementation 'org.springframework.cloud:spring-cloud-config-server'
ConfigApplication.java@EnableConfigServer
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
configサーバのapplication.yml
ファイルに、ポートなどのプリファレンスとサービスごとの設定情報を格納するリポジトリアドレスを入力します.レジストリがプライベートである場合は、ユーザー名、パスワード、Tokenを追加する必要があります.(メッセージエラーがない場合、リクエスト時に不正なエラーが発生します)
application.yml
server:
port: 9020
spring:
application:
name: config-service
cloud:
config:
server:
git:
uri: https://github.com/sgs-ncns/NCNS-Config
username: {username}
password: {password}
サーバを実行し、http://localhost:9020/user-サービス/テスト GETリクエストを送信することで、テストの優先パラメータ情報を正常に読み込むことができます.2.4. Config Client登録
コンフィグ・サーバから設定を受信し、次の依存性をユーザー・サーバ(ユーザー・サーバなど)に追加します.
build.gradle
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
bootstrap.yml
ファイルを生成し、config serverのuriを指定します.必要に応じてprofileを指定して使用します.bootstrap.yml
で作成されたコンテンツは、application.yml
より先にロードされます.したがって、アプリケーションを実行する前に、以前に設定したconfigサーバからプロファイルをロードして実行する必要があります.bootstrap.yml
spring:
cloud:
config:
uri: http://localhost:9020
profile: test
コントローラに次のEndPointを追加して、設定情報が正しく入力されていることを確認できます.UserController.java
public class UserController {
...
@GetMapping("/config")
public String config(@Value("${spring.datasource.url}") String url,
@Value("${spring.datasource.username}") String username,
@Value("${spring.datasource.password}") String password,
@Value("${token.key}") String tokenKey) {
return "url: " + url + "\n"
+ "username: " + username + "\n"
+ "password: " + password + "\n\n"
+ "token key: " + tokenKey;
}
...
}
3.暗号化構成サーバー設定情報
ただしprivate repositoryにアップロードしても、パスワードやsecret keyは純粋なテキストにアップロードすべきではありません.
そこでSpring Cloud Configの暗号化/復号化とJasyptを用いて情報を暗号化する.
3.1. Spring Cloud Configの暗号化/復号化
次の依存項目をConfigサーバに追加して起動します.ymlを有効にします.
build.gradle
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
ブートファイルを作成し、暗号化キーを入力します.bootstrap.yml
encrypt:
key: supersecretencryptkey
次のエンドポイントで暗号化する情報をテキストとしてマスターに送信すると、暗号化文字列が返されます.暗号化:http://config-server.com/encrypt POST
復号化:http://config-server.com/decrypt POST
この文字列を
{ciper}encrypted-string
形式でコンフィギュレーションライブラリに挿入すると適用されます.# user-service.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/ncns_db
username: "{cipher}76ccc5039cd999c9635904f3be4d0f9f7ecbc94445bf283e9df6c9d345d28d0f"
password: "{cipher}a2ae0947fa5e86871198868db6ce2a660440b9fd37b5488ba85471e4b4f4f5d5"
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
use_sql_comments: true
format_sql: true
show_sql: true
hibernate:
ddl-auto: update
generate-ddl: true
token:
key: "{cipher}0edc3d96596eca424ca60bcdf73f05dd82abc7a6d6763a65d744df1e768e3d15"
default:
message: user-service default profiles properties
3.2. Jasypt暗号化
しかし、
bootstrap.yml
は依然として暗号鍵を暴露している.これは、誰もが元のテキストを復号して読むことができることを意味します.したがって、この鍵もJasyptを使用して暗号化されます.実際、Spring Cloud Configを暗号化/復号する必要はなく、このJasyptを使用するだけですべて暗号化できます.
Jasyptを使用する場合は、次の依存項目を追加し、
jasypt.encryptor.password
を設定する必要があります.build.gradle
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4'
Encryptorを詳細に設定するために個別に構成を作成できますが、DefaultLazyEncryptor
はプロジェクト環境変数にパスワードを登録するだけで正常に動作します.@Configuration
public class JasyptConfig {
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("password");
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
テストコードを作成し、簡単な暗号化を行うことができます.Jasyptは複数の暗号化プログラムをサポートしているので、適切な暗号化プログラムを選択できます.
JasyptEncryptTest.java
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class EncryptTest {
@Value("${jasypt.encryptor.password}")
private String encryptorPassword;
private String target;
@Autowired
private ConfigurableEnvironment configurableEnvironment;
@BeforeEach
private void beforeTest() {
target = "plain-text";
}
@Test
public void standardPBEStringEncryptorTest() {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword(encryptorPassword);
System.out.println("StandardPBEStringEncryptor : " + encryptor.encrypt(target));
}
@Test
public void defaultLazyEncryptorTest() {
DefaultLazyEncryptor encryptor = new DefaultLazyEncryptor(configurableEnvironment);
System.out.println("DefaultLazyEncryptor : " + encryptor.encrypt(target));
}
@Test
public void pooledPBEStringEncryptorTest() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setPoolSize(1);
encryptor.setPassword(encryptorPassword);
System.out.println("PooledPBEStringEncryptor : " + encryptor.encrypt(target));
}
}
暗号化文字列はENC(encrypted-string)
形式に変更されます.bootstrap.yml
encrypt:
key: ENC(7gkouBcaWqwM6iEDwLkmibJnTWyvmx4p3uwJqMS5wm5W8feVM54Emfi6WANVjmWm)
🚩 EOD
これで、簡単にMSAプロジェクトを組織する文章は終わりました!
修正や改善が必要な点も多いですが、今回のプロジェクトではMSAを使用する理由とメリットとデメリットを知りました.👏
また、Gatewayから暗号化ツールまで、これらはすべて多くの選択肢があり、それぞれが比較され、プロジェクトに必要なものを分析し、適切な技術を採用するのは面白いプロセスです.
読むだけで堂々としたプロジェクトができる文章をまとめて、これからこの文章を見てくれる人の役に立つことを願っています.🥰
Ref.
OpenFeign vs Rest Template
How should I choose between gRPC and Kafka when building microservices?
マイクロサービス、どのように実施しますか?
マイクロサービスアーキテクチャIPC
マイクロサービスアーキテクチャの通信
https://daddyprogrammer.org/post/4347/spring-cloud-msa-configuration-server/
Spring Cloud Configアプリケーションの設定情報(アプリケーション.yml)を一元管理
[SC 03]Spring Cloud Configとは?
Jasypt暗号化
Spring Boot設定ファイルの暗号化(アプリケーション.yml)
Reference
この問題について([MSA]認証システム開発者(3)-API間の通信と構成サーバ), 我々は、より多くの情報をここで見つけました https://velog.io/@_koiil/Spring-Authentication-System-개발기3テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol