同様のスレッドを見たことがありますが、カスタムを使用しているという点で私のスレッドは異なりますgrant type
。背景を説明すると、別のマイクロサービスからマイクロサービスを呼び出すとき、delegation
呼び出しを開始したユーザーの詳細を持つトークンを使用します。したがって、ユーザーU1はS1を呼び出し、S1はS2を呼び出して、 S2が監査と許可の目的でU1の詳細を使用するようにします。
これを実現するために、次の構成がありますOAuth2RestTemplate
。
@Bean(name = "delegationResource")
@Autowired
public OAuth2ProtectedResourceDetails delegationResource(OAuth2ClientAuthenticationSettings settings) {
OAuth2AuthenticationSettings authSettings = authenticationSettings != null ? authenticationSettings : new OAuth2AuthenticationSettings();
StringBuilder url = new StringBuilder();
url.append(settings.getAuthorisationUrl() != null ? settings.getAuthorisationUrl() : authSettings.getUrl());
url.append(settings.getAccessTokenPath());
DelegationResourceDetails details = new DelegationResourceDetails(authenticationFacade);
details.setClientId(settings.getClientId());
details.setClientSecret(settings.getClientSecret());
details.setAccessTokenUri(url.toString());
details.setGrantType("custom");
if(settings.getScopes() != null) {
details.setScope(Arrays.asList(settings.getScopes()));
}
return details;
}
@Bean(name = "requestScopeClientContext")
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) //Without request-scope, RestTemplate is not thread-safe
public OAuth2ClientContext requestScopeClientContext() {
//This is used for delegation requests and needs to be scoped as request otherwise the first token will be used for all other subsequent calls regardless of what user is initiating it
return new DefaultOAuth2ClientContext();
}
@Autowired
CorrelationIDInterceptor correlationIDInterceptor;
@Bean(name = "delegationOauth2RestTemplate")
//if access to a third party resource is required, a new bean should be created with a @Qualifier
@Autowired
public OAuth2RestTemplate clientCredentialDelegationOauth2RestTemplate(@Qualifier("delegationResource") OAuth2ProtectedResourceDetails delegationResource, @Qualifier("requestScopeClientContext") OAuth2ClientContext sessionScopeClientContext) {
/*
This is used to send requests from a micro-service to another on behalf of the user who initiated the original request
so this has to have a thread-safe client-context
*/
ArrayList<ClientHttpRequestInterceptor> clientHttpRequestInterceptors = new ArrayList<>();
clientHttpRequestInterceptors.add(correlationIDInterceptor);
DelegationOAuth2RestTemplate delegationOAuth2RestTemplate = new DelegationOAuth2RestTemplate(delegationResource, sessionScopeClientContext);
delegationOAuth2RestTemplate.setInterceptors(clientHttpRequestInterceptors);
return delegationOAuth2RestTemplate;
}
ご覧のとおりOAuth2ClientContext
、request
範囲内にある必要があります。そうしないと、以前のユーザーの詳細が使用され、2 番目のユーザーに対してトークン生成が行われなくなります。
ただし、これにはパフォーマンスへの影響があります。多くの同時ユーザーがいる場合、その効果はより顕著になります。そのため、解決策として、OAuth2ClientContext
キャッシュの有効期限をトークンの有効期限よりも小さい値に設定して、ユーザーごとにキャッシュすることを考えています。各トークンはこのポイントを取得する前に検証されるため、キャッシュの有効期限は実際には問題ではありません。
今問題は、これをどのように達成するか、そして最良の方法は何ですか? 私の理解では、スコープをデフォルトのSpring Beanのスコープのように変更request
しsingleton
、キャッシュにエントリがないときに新しいインスタンスを作成する必要がありますか? これを行う方法がわかりませんか?