使用 swagger 生成的 ApiClient 使用 OAuth2 安全 REST API
Consume OAuth2 secured REST API using swagger generated ApiClient
我正在尝试使用由 swagger-codegen-maven-plugin(版本 3.0.0)生成的 ApiClient 从我的 spring 启动应用程序中使用 OAuth2 安全 REST API。身份验证服务器 (keycloak) 提供 JWT 和刷新令牌,但我不知道如何最好地处理我的 bean 中的令牌。
目前我的豆子看起来像这样:
@Configuration
public class SomeApiClientConfiguration {
@Bean
public SomeApi someApi() {
return new SomeApi(apiClient());
}
@Bean
public ApiClient apiClient() {
ApiClient apiClient = new ApiClient();
OAuth oAuth = (OAuth) apiClient.getAuthentication("auth");
oAuth.setAccessToken("");
return apiClient;
}
}
问题是:获取令牌和处理刷新令牌的最佳方法是什么?
编辑:为了获得令牌,我想使用客户端 ID、用户名和密码。授予类型:密码凭据。
最佳,
马克
我已经解决了这个问题,并希望分享解决方案以供将来参考:
这是我的 SomeApiClientConfiguration:
@Configuration
public class SomeApiClientConfiguration{
@Value("${app.api.url}")
private String apiURL;
@Bean
public SomeApi someApi(OAuth2RestTemplate restTemplate) {
return new SomeApi(apiClient(restTemplate));
}
@Bean
public ApiClient apiClient(OAuth2RestTemplate restTemplate) {
var apiClient = new ApiClient(restTemplate);
apiClient.setBasePath(apiURL);
return apiClient;
}
}
另外我需要一个 SomeApiOAuth2Config class,如下所示:
@Configuration
@EnableOAuth2Client
public class SomeApiOAuth2Config {
@Value("${app.api.client-id}")
private String clientId;
@Value("${app.api.token-endpoint}")
private String accessTokenUri;
@Value("${app.api.name}")
private String username;
@Value("${app.api.password}")
private String password;
@Bean
public ClientHttpRequestFactory httpRequestFactory() {
return new HttpComponentsClientHttpRequestFactory(httpClient());
}
@Bean
public HttpClient httpClient() {
var connectionManager = new PoolingHttpClientConnectionManager();
var maxPoolSize = 1;
connectionManager.setMaxTotal(maxPoolSize);
// This client is for internal connections so only one route is expected
connectionManager.setDefaultMaxPerRoute(maxPoolSize);
return HttpClientBuilder.create().setConnectionManager(connectionManager).build();
}
@Bean
public OAuth2ProtectedResourceDetails oauth2ProtectedResourceDetails() {
var details = new ResourceOwnerPasswordResourceDetails();
var resourceId = "";
details.setId(resourceId);
details.setClientId(clientId);
var clientSecret = "";
details.setClientSecret(clientSecret);
details.setAccessTokenUri(accessTokenUri);
details.setClientAuthenticationScheme(AuthenticationScheme.form);
return details;
}
@Bean
public AccessTokenProvider accessTokenProvider() {
var tokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
tokenProvider.setRequestFactory(httpRequestFactory());
return new AccessTokenProviderChain(
Collections.<AccessTokenProvider>singletonList(tokenProvider)
);
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public OAuth2RestTemplate restTemplate(@Qualifier("oauth2ClientContext") OAuth2ClientContext oauth2ClientContext) {
var template = new OAuth2RestTemplate(oauth2ProtectedResourceDetails(), oauth2ClientContext);
template.setRequestFactory(httpRequestFactory());
template.setAccessTokenProvider(accessTokenProvider());
template.getOAuth2ClientContext().getAccessTokenRequest().set("username", username);
template.getOAuth2ClientContext().getAccessTokenRequest().set("password", password);
return template;
}
}
我正在尝试使用由 swagger-codegen-maven-plugin(版本 3.0.0)生成的 ApiClient 从我的 spring 启动应用程序中使用 OAuth2 安全 REST API。身份验证服务器 (keycloak) 提供 JWT 和刷新令牌,但我不知道如何最好地处理我的 bean 中的令牌。 目前我的豆子看起来像这样:
@Configuration
public class SomeApiClientConfiguration {
@Bean
public SomeApi someApi() {
return new SomeApi(apiClient());
}
@Bean
public ApiClient apiClient() {
ApiClient apiClient = new ApiClient();
OAuth oAuth = (OAuth) apiClient.getAuthentication("auth");
oAuth.setAccessToken("");
return apiClient;
}
}
问题是:获取令牌和处理刷新令牌的最佳方法是什么?
编辑:为了获得令牌,我想使用客户端 ID、用户名和密码。授予类型:密码凭据。
最佳,
马克
我已经解决了这个问题,并希望分享解决方案以供将来参考:
这是我的 SomeApiClientConfiguration:
@Configuration
public class SomeApiClientConfiguration{
@Value("${app.api.url}")
private String apiURL;
@Bean
public SomeApi someApi(OAuth2RestTemplate restTemplate) {
return new SomeApi(apiClient(restTemplate));
}
@Bean
public ApiClient apiClient(OAuth2RestTemplate restTemplate) {
var apiClient = new ApiClient(restTemplate);
apiClient.setBasePath(apiURL);
return apiClient;
}
}
另外我需要一个 SomeApiOAuth2Config class,如下所示:
@Configuration
@EnableOAuth2Client
public class SomeApiOAuth2Config {
@Value("${app.api.client-id}")
private String clientId;
@Value("${app.api.token-endpoint}")
private String accessTokenUri;
@Value("${app.api.name}")
private String username;
@Value("${app.api.password}")
private String password;
@Bean
public ClientHttpRequestFactory httpRequestFactory() {
return new HttpComponentsClientHttpRequestFactory(httpClient());
}
@Bean
public HttpClient httpClient() {
var connectionManager = new PoolingHttpClientConnectionManager();
var maxPoolSize = 1;
connectionManager.setMaxTotal(maxPoolSize);
// This client is for internal connections so only one route is expected
connectionManager.setDefaultMaxPerRoute(maxPoolSize);
return HttpClientBuilder.create().setConnectionManager(connectionManager).build();
}
@Bean
public OAuth2ProtectedResourceDetails oauth2ProtectedResourceDetails() {
var details = new ResourceOwnerPasswordResourceDetails();
var resourceId = "";
details.setId(resourceId);
details.setClientId(clientId);
var clientSecret = "";
details.setClientSecret(clientSecret);
details.setAccessTokenUri(accessTokenUri);
details.setClientAuthenticationScheme(AuthenticationScheme.form);
return details;
}
@Bean
public AccessTokenProvider accessTokenProvider() {
var tokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
tokenProvider.setRequestFactory(httpRequestFactory());
return new AccessTokenProviderChain(
Collections.<AccessTokenProvider>singletonList(tokenProvider)
);
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public OAuth2RestTemplate restTemplate(@Qualifier("oauth2ClientContext") OAuth2ClientContext oauth2ClientContext) {
var template = new OAuth2RestTemplate(oauth2ProtectedResourceDetails(), oauth2ClientContext);
template.setRequestFactory(httpRequestFactory());
template.setAccessTokenProvider(accessTokenProvider());
template.getOAuth2ClientContext().getAccessTokenRequest().set("username", username);
template.getOAuth2ClientContext().getAccessTokenRequest().set("password", password);
return template;
}
}