mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-07-03 22:20:56 +00:00
[JAVA][Feign] Replace Apache oltu with scribejava (#8318)
* - Replace apache oltu with scribejava - Implement the following authentication methods - ApiKey header - HTTP basic authentication - Oauth client credentials flow - Oauth Implicit flow - Oauth Pasword (deprecated) * Create class hierarchy for Oauth flows implementation * Add instructions of how to use the ApiClient to Readme.md * Update samples * Remove support for java 6 and 7 * Remove java 6 and 7 support from gradle * Format pom.xml * Remove empty line * Update samples * Remove oltu dependency from build.gradle and build.sbt. Replace oltu with ScribeJava Update samples * Update samples * Update samples
This commit is contained in:
parent
6e4c1307a7
commit
ede2a2316c
@ -392,6 +392,10 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
supportingFiles.add(new SupportingFile("ParamExpander.mustache", invokerFolder, "ParamExpander.java"));
|
||||
supportingFiles.add(new SupportingFile("EncodingUtils.mustache", invokerFolder, "EncodingUtils.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/DefaultApi20Impl.mustache", authFolder, "DefaultApi20Impl.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/OauthPasswordGrant.mustache", authFolder, "OauthPasswordGrant.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/OauthClientCredentialsGrant.mustache", authFolder, "OauthClientCredentialsGrant.java"));
|
||||
|
||||
} else if (OKHTTP_GSON.equals(getLibrary()) || StringUtils.isEmpty(getLibrary())) {
|
||||
// the "okhttp-gson" library template requires "ApiCallback.mustache" for async call
|
||||
supportingFiles.add(new SupportingFile("ApiCallback.mustache", invokerFolder, "ApiCallback.java"));
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -2,11 +2,8 @@ package {{invokerPackage}};
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
{{#hasOAuthMethods}}
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
{{/hasOAuthMethods}}
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
{{#threetenbp}}
|
||||
import org.threeten.bp.*;
|
||||
@ -41,6 +38,8 @@ import {{invokerPackage}}.auth.OAuth.AccessTokenListener;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class ApiClient {
|
||||
private static final Logger log = Logger.getLogger(ApiClient.class.getName());
|
||||
|
||||
public interface Api {}
|
||||
|
||||
protected ObjectMapper objectMapper;
|
||||
@ -60,6 +59,7 @@ public class ApiClient {
|
||||
public ApiClient(String[] authNames) {
|
||||
this();
|
||||
for(String authName : authNames) {
|
||||
log.log(Level.FINE, "Creating authentication {0}", authName);
|
||||
{{#hasAuthMethods}}
|
||||
RequestInterceptor auth;
|
||||
{{#authMethods}}if ("{{name}}".equals(authName)) {
|
||||
@ -75,7 +75,7 @@ public class ApiClient {
|
||||
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{#isKeyInQuery}}"query"{{/isKeyInQuery}}{{#isKeyInCookie}}"cookie"{{/isKeyInCookie}}, "{{keyParamName}}");
|
||||
{{/isApiKey}}
|
||||
{{#isOAuth}}
|
||||
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{^-last}}, {{/-last}}{{/scopes}}");
|
||||
auth = buildOauthRequestInterceptor(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{^-last}}, {{/-last}}{{/scopes}}");
|
||||
{{/isOAuth}}
|
||||
} else {{/authMethods}}{
|
||||
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
|
||||
@ -106,36 +106,6 @@ public class ApiClient {
|
||||
this.setApiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for single basic auth or password oauth2
|
||||
* @param authName
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public ApiClient(String authName, String username, String password) {
|
||||
this(authName);
|
||||
this.setCredentials(username, password);
|
||||
}
|
||||
|
||||
{{#hasOAuthMethods}}
|
||||
/**
|
||||
* Helper constructor for single password oauth2
|
||||
* @param authName
|
||||
* @param clientId
|
||||
* @param secret
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public ApiClient(String authName, String clientId, String secret, String username, String password) {
|
||||
this(authName);
|
||||
this.getTokenEndPoint()
|
||||
.setClientId(clientId)
|
||||
.setClientSecret(secret)
|
||||
.setUsername(username)
|
||||
.setPassword(password);
|
||||
}
|
||||
|
||||
{{/hasOAuthMethods}}
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
@ -190,10 +160,25 @@ public class ApiClient {
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
private RequestInterceptor buildOauthRequestInterceptor(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
switch (flow) {
|
||||
case password:
|
||||
return new OauthPasswordGrant(tokenUrl, scopes);
|
||||
case application:
|
||||
return new OauthClientCredentialsGrant(authorizationUrl, tokenUrl, scopes);
|
||||
default:
|
||||
throw new RuntimeException("Oauth flow \"" + flow + "\" is not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectMapper getObjectMapper(){
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a feign client for given API interface.
|
||||
*
|
||||
@ -240,19 +225,13 @@ public class ApiClient {
|
||||
return contentTypes[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to configure the bearer token.
|
||||
* @param bearerToken the bearer token.
|
||||
*/
|
||||
public void setBearerToken(String bearerToken) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof HttpBearerAuth) {
|
||||
((HttpBearerAuth) apiAuthorization).setBearerToken(bearerToken);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No Bearer authentication configured!");
|
||||
HttpBearerAuth apiAuthorization = getAuthorization(HttpBearerAuth.class);
|
||||
apiAuthorization.setBearerToken(bearerToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,66 +239,39 @@ public class ApiClient {
|
||||
* @param apiKey API key
|
||||
*/
|
||||
public void setApiKey(String apiKey) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof ApiKeyAuth) {
|
||||
ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
|
||||
keyAuth.setApiKey(apiKey);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
ApiKeyAuth apiAuthorization = getAuthorization(ApiKeyAuth.class);
|
||||
apiAuthorization.setApiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the username/password for basic auth or password OAuth
|
||||
* Helper method to configure the username/password for basic auth
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public void setCredentials(String username, String password) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof HttpBasicAuth) {
|
||||
HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
|
||||
basicAuth.setCredentials(username, password);
|
||||
return;
|
||||
}
|
||||
{{#hasOAuthMethods}}
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
|
||||
return;
|
||||
}
|
||||
{{/hasOAuthMethods}}
|
||||
}
|
||||
throw new RuntimeException("No Basic authentication or OAuth configured!");
|
||||
HttpBasicAuth apiAuthorization = getAuthorization(HttpBasicAuth.class);
|
||||
apiAuthorization.setCredentials(username, password);
|
||||
}
|
||||
|
||||
{{#hasOAuthMethods}}
|
||||
/**
|
||||
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Token request builder
|
||||
* Helper method to configure the client credentials for Oauth
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public TokenRequestBuilder getTokenEndPoint() {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
return oauth.getTokenRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public void setClientCredentials(String clientId, String clientSecret) {
|
||||
OauthClientCredentialsGrant authorization = getAuthorization(OauthClientCredentialsGrant.class);
|
||||
authorization.configure(clientId, clientSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Authentication request builder
|
||||
* Helper method to configure the username/password for Oauth password grant
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
return oauth.getAuthenticationRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public void setOauthPassword(String username, String password, String clientId, String clientSecret) {
|
||||
OauthPasswordGrant apiAuthorization = getAuthorization(OauthPasswordGrant.class);
|
||||
apiAuthorization.configure(username, password, clientId, clientSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,14 +279,9 @@ public class ApiClient {
|
||||
* @param accessToken Access Token
|
||||
* @param expiresIn Validity period in seconds
|
||||
*/
|
||||
public void setAccessToken(String accessToken, Long expiresIn) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.setAccessToken(accessToken, expiresIn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
public void setAccessToken(String accessToken, Integer expiresIn) {
|
||||
OAuth apiAuthorization = getAuthorization(OAuth.class);
|
||||
apiAuthorization.setAccessToken(accessToken, expiresIn);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -344,19 +291,7 @@ public class ApiClient {
|
||||
* @param redirectURI Redirect URI
|
||||
*/
|
||||
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.getTokenRequestBuilder()
|
||||
.setClientId(clientId)
|
||||
.setClientSecret(clientSecret)
|
||||
.setRedirectURI(redirectURI);
|
||||
oauth.getAuthenticationRequestBuilder()
|
||||
.setClientId(clientId)
|
||||
.setRedirectURI(redirectURI);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -364,13 +299,8 @@ public class ApiClient {
|
||||
* @param accessTokenListener Acesss token listener
|
||||
*/
|
||||
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.registerAccessTokenListener(accessTokenListener);
|
||||
return;
|
||||
}
|
||||
}
|
||||
OAuth apiAuthorization = getAuthorization(OAuth.class);
|
||||
apiAuthorization.registerAccessTokenListener(accessTokenListener);
|
||||
}
|
||||
|
||||
{{/hasOAuthMethods}}
|
||||
@ -396,4 +326,11 @@ public class ApiClient {
|
||||
feignBuilder.requestInterceptor(authorization);
|
||||
}
|
||||
|
||||
private <T extends RequestInterceptor> T getAuthorization(Class<T> type) {
|
||||
return (T) apiAuthorizations.values()
|
||||
.stream()
|
||||
.filter(requestInterceptor -> type.isAssignableFrom(requestInterceptor.getClass()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("No Oauth authentication or OAuth configured!"));
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,41 @@ After the client library is installed/deployed, you can use it in your Maven pro
|
||||
|
||||
```
|
||||
|
||||
And to use the api you can follow the examples bellow:
|
||||
|
||||
```java
|
||||
|
||||
//Set bearer token manually
|
||||
ApiClient apiClient = new ApiClient("petstore_auth_client");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setAccessToken("TOKEN", 10000);
|
||||
|
||||
//Use api key
|
||||
ApiClient apiClient = new ApiClient("api_key", "API KEY");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
|
||||
//Use http basic authentication
|
||||
ApiClient apiClient = new ApiClient("basicAuth");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setCredentials("username", "password");
|
||||
|
||||
//Oauth password
|
||||
ApiClient apiClient = new ApiClient("oauth_password");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setOauthPassword("username", "password", "client_id", "client_secret");
|
||||
|
||||
//Oauth client credentials flow
|
||||
ApiClient apiClient = new ApiClient("oauth_client_credentials");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setClientCredentials("client_id", "client_secret");
|
||||
|
||||
PetApi petApi = apiClient.buildClient(PetApi.class);
|
||||
Pet petById = petApi.getPetById(12345L);
|
||||
|
||||
System.out.println(petById);
|
||||
}
|
||||
```
|
||||
|
||||
## Recommendation
|
||||
|
||||
It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.
|
||||
@ -40,4 +75,3 @@ It's recommended to create an instance of `ApiClient` per thread in a multithrea
|
||||
|
||||
{{#apiInfo}}{{#apis}}{{#-last}}{{infoEmail}}
|
||||
{{/-last}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
|
47
modules/openapi-generator/src/main/resources/Java/libraries/feign/auth/DefaultApi20Impl.mustache
vendored
Normal file
47
modules/openapi-generator/src/main/resources/Java/libraries/feign/auth/DefaultApi20Impl.mustache
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.api.DefaultApi20;
|
||||
import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor;
|
||||
import com.github.scribejava.core.extractors.TokenExtractor;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.oauth2.bearersignature.BearerSignature;
|
||||
import com.github.scribejava.core.oauth2.bearersignature.BearerSignatureURIQueryParameter;
|
||||
import com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication;
|
||||
import com.github.scribejava.core.oauth2.clientauthentication.RequestBodyAuthenticationScheme;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class DefaultApi20Impl extends DefaultApi20 {
|
||||
|
||||
private final String accessTokenEndpoint;
|
||||
private final String authorizationBaseUrl;
|
||||
|
||||
protected DefaultApi20Impl(String authorizationBaseUrl, String accessTokenEndpoint) {
|
||||
this.authorizationBaseUrl = authorizationBaseUrl;
|
||||
this.accessTokenEndpoint = accessTokenEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTokenEndpoint() {
|
||||
return accessTokenEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAuthorizationBaseUrl() {
|
||||
return authorizationBaseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BearerSignature getBearerSignature() {
|
||||
return BearerSignatureURIQueryParameter.instance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientAuthentication getClientAuthentication() {
|
||||
return RequestBodyAuthenticationScheme.instance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenExtractor<OAuth2AccessToken> getAccessTokenExtractor() {
|
||||
return OAuth2AccessTokenJsonExtractor.instance();
|
||||
}
|
||||
}
|
@ -1,76 +1,34 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.oltu.oauth2.client.HttpClient;
|
||||
import org.apache.oltu.oauth2.client.OAuthClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
import org.apache.oltu.oauth2.common.token.BasicOAuthToken;
|
||||
|
||||
import feign.Client;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.oauth.OAuth20Service;
|
||||
import feign.Request.HttpMethod;
|
||||
import feign.Request.Options;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Response;
|
||||
import feign.RetryableException;
|
||||
import feign.Util;
|
||||
import {{invokerPackage}}.StringUtil;
|
||||
|
||||
|
||||
public class OAuth implements RequestInterceptor {
|
||||
{{>generatedAnnotation}}
|
||||
public abstract class OAuth implements RequestInterceptor {
|
||||
|
||||
static final int MILLIS_PER_SECOND = 1000;
|
||||
|
||||
public interface AccessTokenListener {
|
||||
void notify(BasicOAuthToken token);
|
||||
void notify(OAuth2AccessToken token);
|
||||
}
|
||||
|
||||
private volatile String accessToken;
|
||||
private Long expirationTimeMillis;
|
||||
private OAuthClient oauthClient;
|
||||
private TokenRequestBuilder tokenRequestBuilder;
|
||||
private AuthenticationRequestBuilder authenticationRequestBuilder;
|
||||
private AccessTokenListener accessTokenListener;
|
||||
|
||||
public OAuth(Client client, TokenRequestBuilder requestBuilder) {
|
||||
this.oauthClient = new OAuthClient(new OAuthFeignClient(client));
|
||||
this.tokenRequestBuilder = requestBuilder;
|
||||
}
|
||||
protected OAuth20Service service;
|
||||
protected String scopes;
|
||||
protected String authorizationUrl;
|
||||
protected String tokenUrl;
|
||||
|
||||
public OAuth(Client client, OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this(client, OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
|
||||
|
||||
switch(flow) {
|
||||
case accessCode:
|
||||
case implicit:
|
||||
tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
|
||||
break;
|
||||
case password:
|
||||
tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
|
||||
break;
|
||||
case application:
|
||||
tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
|
||||
}
|
||||
|
||||
public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes);
|
||||
public OAuth(String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this.scopes = scopes;
|
||||
this.authorizationUrl = authorizationUrl;
|
||||
this.tokenUrl = tokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -88,21 +46,25 @@ public class OAuth implements RequestInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void updateAccessToken(RequestTemplate template) {
|
||||
OAuthJSONAccessTokenResponse accessTokenResponse;
|
||||
private synchronized void updateAccessToken(RequestTemplate template) {
|
||||
OAuth2AccessToken accessTokenResponse;
|
||||
try {
|
||||
accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
|
||||
accessTokenResponse = getOAuth2AccessToken();
|
||||
} catch (Exception e) {
|
||||
throw new RetryableException(0, e.getMessage(), HttpMethod.POST, e, null, template.request());
|
||||
}
|
||||
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
|
||||
setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn());
|
||||
if (accessTokenListener != null) {
|
||||
accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
|
||||
accessTokenListener.notify(accessTokenResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract OAuth2AccessToken getOAuth2AccessToken();
|
||||
|
||||
abstract OAuthFlow getFlow();
|
||||
|
||||
public synchronized void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
|
||||
this.accessTokenListener = accessTokenListener;
|
||||
}
|
||||
@ -111,88 +73,9 @@ public class OAuth implements RequestInterceptor {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public synchronized void setAccessToken(String accessToken, Long expiresIn) {
|
||||
public synchronized void setAccessToken(String accessToken, Integer expiresIn) {
|
||||
this.accessToken = accessToken;
|
||||
this.expirationTimeMillis = expiresIn == null ? null : System.currentTimeMillis() + expiresIn * MILLIS_PER_SECOND;
|
||||
}
|
||||
|
||||
public TokenRequestBuilder getTokenRequestBuilder() {
|
||||
return tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public AuthenticationRequestBuilder getAuthenticationRequestBuilder() {
|
||||
return authenticationRequestBuilder;
|
||||
}
|
||||
|
||||
public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) {
|
||||
this.authenticationRequestBuilder = authenticationRequestBuilder;
|
||||
}
|
||||
|
||||
public OAuthClient getOauthClient() {
|
||||
return oauthClient;
|
||||
}
|
||||
|
||||
public void setOauthClient(OAuthClient oauthClient) {
|
||||
this.oauthClient = oauthClient;
|
||||
}
|
||||
|
||||
public void setOauthClient(Client client) {
|
||||
this.oauthClient = new OAuthClient( new OAuthFeignClient(client));
|
||||
}
|
||||
|
||||
public static class OAuthFeignClient implements HttpClient {
|
||||
|
||||
private Client client;
|
||||
|
||||
public OAuthFeignClient() {
|
||||
this.client = new Client.Default(null, null);
|
||||
}
|
||||
|
||||
public OAuthFeignClient(Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
RequestTemplate req = new RequestTemplate()
|
||||
.append(request.getLocationUri())
|
||||
.method(requestMethod)
|
||||
.body(request.getBody());
|
||||
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
req.header(entry.getKey(), entry.getValue());
|
||||
}
|
||||
Response feignResponse;
|
||||
String body = "";
|
||||
try {
|
||||
feignResponse = client.execute(req.request(), new Options());
|
||||
body = Util.toString(feignResponse.body().asReader());
|
||||
} catch (IOException e) {
|
||||
throw new OAuthSystemException(e);
|
||||
}
|
||||
|
||||
String contentType = null;
|
||||
Collection<String> contentTypeHeader = feignResponse.headers().get("Content-Type");
|
||||
if(contentTypeHeader != null) {
|
||||
contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";");
|
||||
}
|
||||
|
||||
return OAuthClientResponseFactory.createCustomResponse(
|
||||
body,
|
||||
contentType,
|
||||
feignResponse.status(),
|
||||
responseClass
|
||||
);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class OauthClientCredentialsGrant extends OAuth {
|
||||
|
||||
public OauthClientCredentialsGrant(String authorizationUrl, String tokenUrl, String scopes) {
|
||||
super(authorizationUrl, tokenUrl, scopes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2AccessToken getOAuth2AccessToken() {
|
||||
try {
|
||||
return service.getAccessTokenClientCredentialsGrant(scopes);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get oauth token", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuthFlow getFlow() {
|
||||
return OAuthFlow.application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the client credentials flow
|
||||
*
|
||||
* @param clientId
|
||||
* @param clientSecret
|
||||
*/
|
||||
public void configure(String clientId, String clientSecret) {
|
||||
service = new ServiceBuilder(clientId)
|
||||
.apiSecret(clientSecret)
|
||||
.defaultScope(scopes)
|
||||
.build(new DefaultApi20Impl(authorizationUrl, tokenUrl));
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class OauthPasswordGrant extends OAuth {
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public OauthPasswordGrant(String tokenUrl, String scopes) {
|
||||
super(null, tokenUrl, scopes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2AccessToken getOAuth2AccessToken() {
|
||||
try {
|
||||
return service.getAccessTokenPasswordGrant(username, password);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get oauth token", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuthFlow getFlow() {
|
||||
return OAuthFlow.password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Oauth password grant flow
|
||||
* Note: this flow is deprecated.
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @param clientId
|
||||
* @param clientSecret
|
||||
*/
|
||||
public void configure(String username, String password, String clientId, String clientSecret) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
//TODO the clientId and secret are optional according with the RFC
|
||||
service = new ServiceBuilder(clientId)
|
||||
.apiSecret(clientSecret)
|
||||
.defaultScope(scopes)
|
||||
.build(new DefaultApi20Impl(authorizationUrl, tokenUrl));
|
||||
}
|
||||
}
|
@ -33,20 +33,8 @@ if(hasProperty('target') && target == 'android') {
|
||||
targetSdkVersion 25
|
||||
}
|
||||
compileOptions {
|
||||
{{#supportJava6}}
|
||||
sourceCompatibility JavaVersion.VERSION_1_6
|
||||
targetCompatibility JavaVersion.VERSION_1_6
|
||||
{{/supportJava6}}
|
||||
{{^supportJava6}}
|
||||
{{#java8}}
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
{{/java8}}
|
||||
{{^java8}}
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
{{/java8}}
|
||||
{{/supportJava6}}
|
||||
}
|
||||
|
||||
// Rename the aar correctly
|
||||
@ -91,20 +79,8 @@ if(hasProperty('target') && target == 'android') {
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
{{#supportJava6}}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_6
|
||||
targetCompatibility = JavaVersion.VERSION_1_6
|
||||
{{/supportJava6}}
|
||||
{{^supportJava6}}
|
||||
{{#java8}}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
{{/java8}}
|
||||
{{^java8}}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
{{/java8}}
|
||||
{{/supportJava6}}
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
@ -131,7 +107,7 @@ ext {
|
||||
feign_version = "10.11"
|
||||
feign_form_version = "3.8.0"
|
||||
junit_version = "4.13.1"
|
||||
oltu_version = "1.0.1"
|
||||
scribejava_version = "8.0.0"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -156,7 +132,8 @@ dependencies {
|
||||
{{#threetenbp}}
|
||||
implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_threetenbp_version"
|
||||
{{/threetenbp}}
|
||||
implementation "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version"
|
||||
implementation "com.brsanthu:migbase64:2.2"
|
||||
implementation "com.github.scribejava:scribejava-core:$scribejava_version"
|
||||
implementation "com.brsanthu:migbase64:2.2"
|
||||
implementation 'javax.annotation:javax.annotation-api:1.3.2'
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
|
@ -19,7 +19,7 @@ lazy val root = (project in file(".")).
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.10.3" % "compile",
|
||||
"com.fasterxml.jackson.datatype" % "jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}" % "2.9.10" % "compile",
|
||||
"com.github.joschi.jackson" % "jackson-datatype-threetenbp" % "2.9.10" % "compile",
|
||||
"org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile",
|
||||
"com.github.scribejava" % "scribejava-core" % "8.0.0" % "compile",
|
||||
"com.brsanthu" % "migbase64" % "2.2" % "compile",
|
||||
"javax.annotation" % "javax.annotation-api" % "1.3.2" % "compile",
|
||||
"junit" % "junit" % "4.13.1" % "test",
|
||||
|
@ -161,17 +161,7 @@
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<doclint>none</doclint>
|
||||
{{#supportJava6}}
|
||||
<source>1.6</source>
|
||||
{{/supportJava6}}
|
||||
{{^supportJava6}}
|
||||
{{#java8}}
|
||||
<source>1.8</source>
|
||||
{{/java8}}
|
||||
{{^java8}}
|
||||
<source>1.7</source>
|
||||
{{/java8}}
|
||||
{{/supportJava6}}
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
@ -282,14 +272,12 @@
|
||||
</dependency>
|
||||
{{/openApiNullable}}
|
||||
{{#withXml}}
|
||||
|
||||
<!-- XML Support -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
<version>${jackson-version}</version>
|
||||
</dependency>
|
||||
|
||||
{{/withXml}}
|
||||
{{#joda}}
|
||||
<dependency>
|
||||
@ -313,9 +301,9 @@
|
||||
</dependency>
|
||||
{{/threetenbp}}
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>${oltu-version}</version>
|
||||
<groupId>com.github.scribejava</groupId>
|
||||
<artifactId>scribejava-core</artifactId>
|
||||
<version>${scribejava-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
@ -346,7 +334,7 @@
|
||||
</dependencies>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>{{#supportJava6}}1.6{{/supportJava6}}{{^supportJava6}}{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}{{/supportJava6}}</java.version>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<swagger-annotations-version>1.5.24</swagger-annotations-version>
|
||||
@ -363,6 +351,6 @@
|
||||
<javax-annotation-version>1.3.2</javax-annotation-version>
|
||||
<junit-version>4.13.1</junit-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<oltu-version>1.0.1</oltu-version>
|
||||
<scribejava-version>8.0.0</scribejava-version>
|
||||
</properties>
|
||||
</project>
|
||||
|
@ -28,10 +28,13 @@ src/main/java/org/openapitools/client/api/PetApi.java
|
||||
src/main/java/org/openapitools/client/api/StoreApi.java
|
||||
src/main/java/org/openapitools/client/api/UserApi.java
|
||||
src/main/java/org/openapitools/client/auth/ApiKeyAuth.java
|
||||
src/main/java/org/openapitools/client/auth/DefaultApi20Impl.java
|
||||
src/main/java/org/openapitools/client/auth/HttpBasicAuth.java
|
||||
src/main/java/org/openapitools/client/auth/HttpBearerAuth.java
|
||||
src/main/java/org/openapitools/client/auth/OAuth.java
|
||||
src/main/java/org/openapitools/client/auth/OAuthFlow.java
|
||||
src/main/java/org/openapitools/client/auth/OauthClientCredentialsGrant.java
|
||||
src/main/java/org/openapitools/client/auth/OauthPasswordGrant.java
|
||||
src/main/java/org/openapitools/client/model/AdditionalPropertiesAnyType.java
|
||||
src/main/java/org/openapitools/client/model/AdditionalPropertiesArray.java
|
||||
src/main/java/org/openapitools/client/model/AdditionalPropertiesBoolean.java
|
||||
|
@ -32,6 +32,41 @@ After the client library is installed/deployed, you can use it in your Maven pro
|
||||
|
||||
```
|
||||
|
||||
And to use the api you can follow the examples bellow:
|
||||
|
||||
```java
|
||||
|
||||
//Set bearer token manually
|
||||
ApiClient apiClient = new ApiClient("petstore_auth_client");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setAccessToken("TOKEN", 10000);
|
||||
|
||||
//Use api key
|
||||
ApiClient apiClient = new ApiClient("api_key", "API KEY");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
|
||||
//Use http basic authentication
|
||||
ApiClient apiClient = new ApiClient("basicAuth");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setCredentials("username", "password");
|
||||
|
||||
//Oauth password
|
||||
ApiClient apiClient = new ApiClient("oauth_password");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setOauthPassword("username", "password", "client_id", "client_secret");
|
||||
|
||||
//Oauth client credentials flow
|
||||
ApiClient apiClient = new ApiClient("oauth_client_credentials");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setClientCredentials("client_id", "client_secret");
|
||||
|
||||
PetApi petApi = apiClient.buildClient(PetApi.class);
|
||||
Pet petById = petApi.getPetById(12345L);
|
||||
|
||||
System.out.println(petById);
|
||||
}
|
||||
```
|
||||
|
||||
## Recommendation
|
||||
|
||||
It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.
|
||||
@ -40,4 +75,3 @@ It's recommended to create an instance of `ApiClient` per thread in a multithrea
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -33,8 +33,8 @@ if(hasProperty('target') && target == 'android') {
|
||||
targetSdkVersion 25
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
// Rename the aar correctly
|
||||
@ -79,8 +79,8 @@ if(hasProperty('target') && target == 'android') {
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
@ -102,7 +102,7 @@ ext {
|
||||
feign_version = "10.11"
|
||||
feign_form_version = "3.8.0"
|
||||
junit_version = "4.13.1"
|
||||
oltu_version = "1.0.1"
|
||||
scribejava_version = "8.0.0"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -116,7 +116,8 @@ dependencies {
|
||||
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
|
||||
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_databind_version"
|
||||
implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_threetenbp_version"
|
||||
implementation "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version"
|
||||
implementation "com.brsanthu:migbase64:2.2"
|
||||
implementation "com.github.scribejava:scribejava-core:$scribejava_version"
|
||||
implementation "com.brsanthu:migbase64:2.2"
|
||||
implementation 'javax.annotation:javax.annotation-api:1.3.2'
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
|
@ -19,7 +19,7 @@ lazy val root = (project in file(".")).
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.10.3" % "compile",
|
||||
"com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.9.10" % "compile",
|
||||
"com.github.joschi.jackson" % "jackson-datatype-threetenbp" % "2.9.10" % "compile",
|
||||
"org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile",
|
||||
"com.github.scribejava" % "scribejava-core" % "8.0.0" % "compile",
|
||||
"com.brsanthu" % "migbase64" % "2.2" % "compile",
|
||||
"javax.annotation" % "javax.annotation-api" % "1.3.2" % "compile",
|
||||
"junit" % "junit" % "4.13.1" % "test",
|
||||
|
@ -154,7 +154,7 @@
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<doclint>none</doclint>
|
||||
<source>1.7</source>
|
||||
<source>1.8</source>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
@ -263,9 +263,9 @@
|
||||
<version>${jackson-threetenbp-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>${oltu-version}</version>
|
||||
<groupId>com.github.scribejava</groupId>
|
||||
<artifactId>scribejava-core</artifactId>
|
||||
<version>${scribejava-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
@ -296,7 +296,7 @@
|
||||
</dependencies>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.7</java.version>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<swagger-annotations-version>1.5.24</swagger-annotations-version>
|
||||
@ -308,6 +308,6 @@
|
||||
<javax-annotation-version>1.3.2</javax-annotation-version>
|
||||
<junit-version>4.13.1</junit-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<oltu-version>1.0.1</oltu-version>
|
||||
<scribejava-version>8.0.0</scribejava-version>
|
||||
</properties>
|
||||
</project>
|
||||
|
@ -2,9 +2,8 @@ package org.openapitools.client;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.threeten.bp.*;
|
||||
|
||||
@ -24,6 +23,8 @@ import org.openapitools.client.auth.OAuth.AccessTokenListener;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public class ApiClient {
|
||||
private static final Logger log = Logger.getLogger(ApiClient.class.getName());
|
||||
|
||||
public interface Api {}
|
||||
|
||||
protected ObjectMapper objectMapper;
|
||||
@ -43,6 +44,7 @@ public class ApiClient {
|
||||
public ApiClient(String[] authNames) {
|
||||
this();
|
||||
for(String authName : authNames) {
|
||||
log.log(Level.FINE, "Creating authentication {0}", authName);
|
||||
RequestInterceptor auth;
|
||||
if ("api_key".equals(authName)) {
|
||||
auth = new ApiKeyAuth("header", "api_key");
|
||||
@ -51,7 +53,7 @@ public class ApiClient {
|
||||
} else if ("http_basic_test".equals(authName)) {
|
||||
auth = new HttpBasicAuth();
|
||||
} else if ("petstore_auth".equals(authName)) {
|
||||
auth = new OAuth(OAuthFlow.implicit, "http://petstore.swagger.io/api/oauth/dialog", "", "write:pets, read:pets");
|
||||
auth = buildOauthRequestInterceptor(OAuthFlow.implicit, "http://petstore.swagger.io/api/oauth/dialog", "", "write:pets, read:pets");
|
||||
} else {
|
||||
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
|
||||
}
|
||||
@ -77,34 +79,6 @@ public class ApiClient {
|
||||
this.setApiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for single basic auth or password oauth2
|
||||
* @param authName
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public ApiClient(String authName, String username, String password) {
|
||||
this(authName);
|
||||
this.setCredentials(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for single password oauth2
|
||||
* @param authName
|
||||
* @param clientId
|
||||
* @param secret
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public ApiClient(String authName, String clientId, String secret, String username, String password) {
|
||||
this(authName);
|
||||
this.getTokenEndPoint()
|
||||
.setClientId(clientId)
|
||||
.setClientSecret(secret)
|
||||
.setUsername(username)
|
||||
.setPassword(password);
|
||||
}
|
||||
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
@ -147,10 +121,25 @@ public class ApiClient {
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
private RequestInterceptor buildOauthRequestInterceptor(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
switch (flow) {
|
||||
case password:
|
||||
return new OauthPasswordGrant(tokenUrl, scopes);
|
||||
case application:
|
||||
return new OauthClientCredentialsGrant(authorizationUrl, tokenUrl, scopes);
|
||||
default:
|
||||
throw new RuntimeException("Oauth flow \"" + flow + "\" is not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectMapper getObjectMapper(){
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a feign client for given API interface.
|
||||
*
|
||||
@ -197,19 +186,13 @@ public class ApiClient {
|
||||
return contentTypes[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to configure the bearer token.
|
||||
* @param bearerToken the bearer token.
|
||||
*/
|
||||
public void setBearerToken(String bearerToken) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof HttpBearerAuth) {
|
||||
((HttpBearerAuth) apiAuthorization).setBearerToken(bearerToken);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No Bearer authentication configured!");
|
||||
HttpBearerAuth apiAuthorization = getAuthorization(HttpBearerAuth.class);
|
||||
apiAuthorization.setBearerToken(bearerToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,63 +200,38 @@ public class ApiClient {
|
||||
* @param apiKey API key
|
||||
*/
|
||||
public void setApiKey(String apiKey) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof ApiKeyAuth) {
|
||||
ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
|
||||
keyAuth.setApiKey(apiKey);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
ApiKeyAuth apiAuthorization = getAuthorization(ApiKeyAuth.class);
|
||||
apiAuthorization.setApiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the username/password for basic auth or password OAuth
|
||||
* Helper method to configure the username/password for basic auth
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public void setCredentials(String username, String password) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof HttpBasicAuth) {
|
||||
HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
|
||||
basicAuth.setCredentials(username, password);
|
||||
return;
|
||||
}
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No Basic authentication or OAuth configured!");
|
||||
HttpBasicAuth apiAuthorization = getAuthorization(HttpBasicAuth.class);
|
||||
apiAuthorization.setCredentials(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Token request builder
|
||||
* Helper method to configure the client credentials for Oauth
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public TokenRequestBuilder getTokenEndPoint() {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
return oauth.getTokenRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public void setClientCredentials(String clientId, String clientSecret) {
|
||||
OauthClientCredentialsGrant authorization = getAuthorization(OauthClientCredentialsGrant.class);
|
||||
authorization.configure(clientId, clientSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Authentication request builder
|
||||
* Helper method to configure the username/password for Oauth password grant
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
return oauth.getAuthenticationRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public void setOauthPassword(String username, String password, String clientId, String clientSecret) {
|
||||
OauthPasswordGrant apiAuthorization = getAuthorization(OauthPasswordGrant.class);
|
||||
apiAuthorization.configure(username, password, clientId, clientSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,14 +239,9 @@ public class ApiClient {
|
||||
* @param accessToken Access Token
|
||||
* @param expiresIn Validity period in seconds
|
||||
*/
|
||||
public void setAccessToken(String accessToken, Long expiresIn) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.setAccessToken(accessToken, expiresIn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
public void setAccessToken(String accessToken, Integer expiresIn) {
|
||||
OAuth apiAuthorization = getAuthorization(OAuth.class);
|
||||
apiAuthorization.setAccessToken(accessToken, expiresIn);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -298,19 +251,7 @@ public class ApiClient {
|
||||
* @param redirectURI Redirect URI
|
||||
*/
|
||||
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.getTokenRequestBuilder()
|
||||
.setClientId(clientId)
|
||||
.setClientSecret(clientSecret)
|
||||
.setRedirectURI(redirectURI);
|
||||
oauth.getAuthenticationRequestBuilder()
|
||||
.setClientId(clientId)
|
||||
.setRedirectURI(redirectURI);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,13 +259,8 @@ public class ApiClient {
|
||||
* @param accessTokenListener Acesss token listener
|
||||
*/
|
||||
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.registerAccessTokenListener(accessTokenListener);
|
||||
return;
|
||||
}
|
||||
}
|
||||
OAuth apiAuthorization = getAuthorization(OAuth.class);
|
||||
apiAuthorization.registerAccessTokenListener(accessTokenListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -349,4 +285,11 @@ public class ApiClient {
|
||||
feignBuilder.requestInterceptor(authorization);
|
||||
}
|
||||
|
||||
private <T extends RequestInterceptor> T getAuthorization(Class<T> type) {
|
||||
return (T) apiAuthorizations.values()
|
||||
.stream()
|
||||
.filter(requestInterceptor -> type.isAssignableFrom(requestInterceptor.getClass()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("No Oauth authentication or OAuth configured!"));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.api.DefaultApi20;
|
||||
import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor;
|
||||
import com.github.scribejava.core.extractors.TokenExtractor;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.oauth2.bearersignature.BearerSignature;
|
||||
import com.github.scribejava.core.oauth2.bearersignature.BearerSignatureURIQueryParameter;
|
||||
import com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication;
|
||||
import com.github.scribejava.core.oauth2.clientauthentication.RequestBodyAuthenticationScheme;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public class DefaultApi20Impl extends DefaultApi20 {
|
||||
|
||||
private final String accessTokenEndpoint;
|
||||
private final String authorizationBaseUrl;
|
||||
|
||||
protected DefaultApi20Impl(String authorizationBaseUrl, String accessTokenEndpoint) {
|
||||
this.authorizationBaseUrl = authorizationBaseUrl;
|
||||
this.accessTokenEndpoint = accessTokenEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTokenEndpoint() {
|
||||
return accessTokenEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAuthorizationBaseUrl() {
|
||||
return authorizationBaseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BearerSignature getBearerSignature() {
|
||||
return BearerSignatureURIQueryParameter.instance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientAuthentication getClientAuthentication() {
|
||||
return RequestBodyAuthenticationScheme.instance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenExtractor<OAuth2AccessToken> getAccessTokenExtractor() {
|
||||
return OAuth2AccessTokenJsonExtractor.instance();
|
||||
}
|
||||
}
|
@ -1,76 +1,34 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.oltu.oauth2.client.HttpClient;
|
||||
import org.apache.oltu.oauth2.client.OAuthClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
import org.apache.oltu.oauth2.common.token.BasicOAuthToken;
|
||||
|
||||
import feign.Client;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.oauth.OAuth20Service;
|
||||
import feign.Request.HttpMethod;
|
||||
import feign.Request.Options;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Response;
|
||||
import feign.RetryableException;
|
||||
import feign.Util;
|
||||
import org.openapitools.client.StringUtil;
|
||||
|
||||
|
||||
public class OAuth implements RequestInterceptor {
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public abstract class OAuth implements RequestInterceptor {
|
||||
|
||||
static final int MILLIS_PER_SECOND = 1000;
|
||||
|
||||
public interface AccessTokenListener {
|
||||
void notify(BasicOAuthToken token);
|
||||
void notify(OAuth2AccessToken token);
|
||||
}
|
||||
|
||||
private volatile String accessToken;
|
||||
private Long expirationTimeMillis;
|
||||
private OAuthClient oauthClient;
|
||||
private TokenRequestBuilder tokenRequestBuilder;
|
||||
private AuthenticationRequestBuilder authenticationRequestBuilder;
|
||||
private AccessTokenListener accessTokenListener;
|
||||
|
||||
public OAuth(Client client, TokenRequestBuilder requestBuilder) {
|
||||
this.oauthClient = new OAuthClient(new OAuthFeignClient(client));
|
||||
this.tokenRequestBuilder = requestBuilder;
|
||||
}
|
||||
protected OAuth20Service service;
|
||||
protected String scopes;
|
||||
protected String authorizationUrl;
|
||||
protected String tokenUrl;
|
||||
|
||||
public OAuth(Client client, OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this(client, OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
|
||||
|
||||
switch(flow) {
|
||||
case accessCode:
|
||||
case implicit:
|
||||
tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
|
||||
break;
|
||||
case password:
|
||||
tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
|
||||
break;
|
||||
case application:
|
||||
tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
|
||||
}
|
||||
|
||||
public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes);
|
||||
public OAuth(String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this.scopes = scopes;
|
||||
this.authorizationUrl = authorizationUrl;
|
||||
this.tokenUrl = tokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -88,21 +46,25 @@ public class OAuth implements RequestInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void updateAccessToken(RequestTemplate template) {
|
||||
OAuthJSONAccessTokenResponse accessTokenResponse;
|
||||
private synchronized void updateAccessToken(RequestTemplate template) {
|
||||
OAuth2AccessToken accessTokenResponse;
|
||||
try {
|
||||
accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
|
||||
accessTokenResponse = getOAuth2AccessToken();
|
||||
} catch (Exception e) {
|
||||
throw new RetryableException(0, e.getMessage(), HttpMethod.POST, e, null, template.request());
|
||||
}
|
||||
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
|
||||
setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn());
|
||||
if (accessTokenListener != null) {
|
||||
accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
|
||||
accessTokenListener.notify(accessTokenResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract OAuth2AccessToken getOAuth2AccessToken();
|
||||
|
||||
abstract OAuthFlow getFlow();
|
||||
|
||||
public synchronized void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
|
||||
this.accessTokenListener = accessTokenListener;
|
||||
}
|
||||
@ -111,88 +73,9 @@ public class OAuth implements RequestInterceptor {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public synchronized void setAccessToken(String accessToken, Long expiresIn) {
|
||||
public synchronized void setAccessToken(String accessToken, Integer expiresIn) {
|
||||
this.accessToken = accessToken;
|
||||
this.expirationTimeMillis = expiresIn == null ? null : System.currentTimeMillis() + expiresIn * MILLIS_PER_SECOND;
|
||||
}
|
||||
|
||||
public TokenRequestBuilder getTokenRequestBuilder() {
|
||||
return tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public AuthenticationRequestBuilder getAuthenticationRequestBuilder() {
|
||||
return authenticationRequestBuilder;
|
||||
}
|
||||
|
||||
public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) {
|
||||
this.authenticationRequestBuilder = authenticationRequestBuilder;
|
||||
}
|
||||
|
||||
public OAuthClient getOauthClient() {
|
||||
return oauthClient;
|
||||
}
|
||||
|
||||
public void setOauthClient(OAuthClient oauthClient) {
|
||||
this.oauthClient = oauthClient;
|
||||
}
|
||||
|
||||
public void setOauthClient(Client client) {
|
||||
this.oauthClient = new OAuthClient( new OAuthFeignClient(client));
|
||||
}
|
||||
|
||||
public static class OAuthFeignClient implements HttpClient {
|
||||
|
||||
private Client client;
|
||||
|
||||
public OAuthFeignClient() {
|
||||
this.client = new Client.Default(null, null);
|
||||
}
|
||||
|
||||
public OAuthFeignClient(Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
RequestTemplate req = new RequestTemplate()
|
||||
.append(request.getLocationUri())
|
||||
.method(requestMethod)
|
||||
.body(request.getBody());
|
||||
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
req.header(entry.getKey(), entry.getValue());
|
||||
}
|
||||
Response feignResponse;
|
||||
String body = "";
|
||||
try {
|
||||
feignResponse = client.execute(req.request(), new Options());
|
||||
body = Util.toString(feignResponse.body().asReader());
|
||||
} catch (IOException e) {
|
||||
throw new OAuthSystemException(e);
|
||||
}
|
||||
|
||||
String contentType = null;
|
||||
Collection<String> contentTypeHeader = feignResponse.headers().get("Content-Type");
|
||||
if(contentTypeHeader != null) {
|
||||
contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";");
|
||||
}
|
||||
|
||||
return OAuthClientResponseFactory.createCustomResponse(
|
||||
body,
|
||||
contentType,
|
||||
feignResponse.status(),
|
||||
responseClass
|
||||
);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public class OauthClientCredentialsGrant extends OAuth {
|
||||
|
||||
public OauthClientCredentialsGrant(String authorizationUrl, String tokenUrl, String scopes) {
|
||||
super(authorizationUrl, tokenUrl, scopes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2AccessToken getOAuth2AccessToken() {
|
||||
try {
|
||||
return service.getAccessTokenClientCredentialsGrant(scopes);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get oauth token", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuthFlow getFlow() {
|
||||
return OAuthFlow.application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the client credentials flow
|
||||
*
|
||||
* @param clientId
|
||||
* @param clientSecret
|
||||
*/
|
||||
public void configure(String clientId, String clientSecret) {
|
||||
service = new ServiceBuilder(clientId)
|
||||
.apiSecret(clientSecret)
|
||||
.defaultScope(scopes)
|
||||
.build(new DefaultApi20Impl(authorizationUrl, tokenUrl));
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public class OauthPasswordGrant extends OAuth {
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public OauthPasswordGrant(String tokenUrl, String scopes) {
|
||||
super(null, tokenUrl, scopes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2AccessToken getOAuth2AccessToken() {
|
||||
try {
|
||||
return service.getAccessTokenPasswordGrant(username, password);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get oauth token", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuthFlow getFlow() {
|
||||
return OAuthFlow.password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Oauth password grant flow
|
||||
* Note: this flow is deprecated.
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @param clientId
|
||||
* @param clientSecret
|
||||
*/
|
||||
public void configure(String username, String password, String clientId, String clientSecret) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
//TODO the clientId and secret are optional according with the RFC
|
||||
service = new ServiceBuilder(clientId)
|
||||
.apiSecret(clientSecret)
|
||||
.defaultScope(scopes)
|
||||
.build(new DefaultApi20Impl(authorizationUrl, tokenUrl));
|
||||
}
|
||||
}
|
@ -28,10 +28,13 @@ src/main/java/org/openapitools/client/api/PetApi.java
|
||||
src/main/java/org/openapitools/client/api/StoreApi.java
|
||||
src/main/java/org/openapitools/client/api/UserApi.java
|
||||
src/main/java/org/openapitools/client/auth/ApiKeyAuth.java
|
||||
src/main/java/org/openapitools/client/auth/DefaultApi20Impl.java
|
||||
src/main/java/org/openapitools/client/auth/HttpBasicAuth.java
|
||||
src/main/java/org/openapitools/client/auth/HttpBearerAuth.java
|
||||
src/main/java/org/openapitools/client/auth/OAuth.java
|
||||
src/main/java/org/openapitools/client/auth/OAuthFlow.java
|
||||
src/main/java/org/openapitools/client/auth/OauthClientCredentialsGrant.java
|
||||
src/main/java/org/openapitools/client/auth/OauthPasswordGrant.java
|
||||
src/main/java/org/openapitools/client/model/AdditionalPropertiesAnyType.java
|
||||
src/main/java/org/openapitools/client/model/AdditionalPropertiesArray.java
|
||||
src/main/java/org/openapitools/client/model/AdditionalPropertiesBoolean.java
|
||||
|
@ -32,6 +32,41 @@ After the client library is installed/deployed, you can use it in your Maven pro
|
||||
|
||||
```
|
||||
|
||||
And to use the api you can follow the examples bellow:
|
||||
|
||||
```java
|
||||
|
||||
//Set bearer token manually
|
||||
ApiClient apiClient = new ApiClient("petstore_auth_client");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setAccessToken("TOKEN", 10000);
|
||||
|
||||
//Use api key
|
||||
ApiClient apiClient = new ApiClient("api_key", "API KEY");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
|
||||
//Use http basic authentication
|
||||
ApiClient apiClient = new ApiClient("basicAuth");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setCredentials("username", "password");
|
||||
|
||||
//Oauth password
|
||||
ApiClient apiClient = new ApiClient("oauth_password");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setOauthPassword("username", "password", "client_id", "client_secret");
|
||||
|
||||
//Oauth client credentials flow
|
||||
ApiClient apiClient = new ApiClient("oauth_client_credentials");
|
||||
apiClient.setBasePath("https://localhost:8243/petstore/1/");
|
||||
apiClient.setClientCredentials("client_id", "client_secret");
|
||||
|
||||
PetApi petApi = apiClient.buildClient(PetApi.class);
|
||||
Pet petById = petApi.getPetById(12345L);
|
||||
|
||||
System.out.println(petById);
|
||||
}
|
||||
```
|
||||
|
||||
## Recommendation
|
||||
|
||||
It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.
|
||||
@ -40,4 +75,3 @@ It's recommended to create an instance of `ApiClient` per thread in a multithrea
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -33,8 +33,8 @@ if(hasProperty('target') && target == 'android') {
|
||||
targetSdkVersion 25
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
// Rename the aar correctly
|
||||
@ -79,8 +79,8 @@ if(hasProperty('target') && target == 'android') {
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
@ -103,7 +103,7 @@ ext {
|
||||
feign_version = "10.11"
|
||||
feign_form_version = "3.8.0"
|
||||
junit_version = "4.13.1"
|
||||
oltu_version = "1.0.1"
|
||||
scribejava_version = "8.0.0"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -118,7 +118,8 @@ dependencies {
|
||||
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_databind_version"
|
||||
implementation "org.openapitools:jackson-databind-nullable:$jackson_databind_nullable_version"
|
||||
implementation "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_threetenbp_version"
|
||||
implementation "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version"
|
||||
implementation "com.brsanthu:migbase64:2.2"
|
||||
implementation "com.github.scribejava:scribejava-core:$scribejava_version"
|
||||
implementation "com.brsanthu:migbase64:2.2"
|
||||
implementation 'javax.annotation:javax.annotation-api:1.3.2'
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
|
@ -19,7 +19,7 @@ lazy val root = (project in file(".")).
|
||||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.10.3" % "compile",
|
||||
"com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.9.10" % "compile",
|
||||
"com.github.joschi.jackson" % "jackson-datatype-threetenbp" % "2.9.10" % "compile",
|
||||
"org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile",
|
||||
"com.github.scribejava" % "scribejava-core" % "8.0.0" % "compile",
|
||||
"com.brsanthu" % "migbase64" % "2.2" % "compile",
|
||||
"javax.annotation" % "javax.annotation-api" % "1.3.2" % "compile",
|
||||
"junit" % "junit" % "4.13.1" % "test",
|
||||
|
@ -154,7 +154,7 @@
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<doclint>none</doclint>
|
||||
<source>1.7</source>
|
||||
<source>1.8</source>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
@ -268,9 +268,9 @@
|
||||
<version>${jackson-threetenbp-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>${oltu-version}</version>
|
||||
<groupId>com.github.scribejava</groupId>
|
||||
<artifactId>scribejava-core</artifactId>
|
||||
<version>${scribejava-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
@ -301,7 +301,7 @@
|
||||
</dependencies>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.7</java.version>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<swagger-annotations-version>1.5.24</swagger-annotations-version>
|
||||
@ -314,6 +314,6 @@
|
||||
<javax-annotation-version>1.3.2</javax-annotation-version>
|
||||
<junit-version>4.13.1</junit-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<oltu-version>1.0.1</oltu-version>
|
||||
<scribejava-version>8.0.0</scribejava-version>
|
||||
</properties>
|
||||
</project>
|
||||
|
@ -2,9 +2,8 @@ package org.openapitools.client;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.threeten.bp.*;
|
||||
|
||||
@ -25,6 +24,8 @@ import org.openapitools.client.auth.OAuth.AccessTokenListener;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public class ApiClient {
|
||||
private static final Logger log = Logger.getLogger(ApiClient.class.getName());
|
||||
|
||||
public interface Api {}
|
||||
|
||||
protected ObjectMapper objectMapper;
|
||||
@ -44,6 +45,7 @@ public class ApiClient {
|
||||
public ApiClient(String[] authNames) {
|
||||
this();
|
||||
for(String authName : authNames) {
|
||||
log.log(Level.FINE, "Creating authentication {0}", authName);
|
||||
RequestInterceptor auth;
|
||||
if ("api_key".equals(authName)) {
|
||||
auth = new ApiKeyAuth("header", "api_key");
|
||||
@ -52,7 +54,7 @@ public class ApiClient {
|
||||
} else if ("http_basic_test".equals(authName)) {
|
||||
auth = new HttpBasicAuth();
|
||||
} else if ("petstore_auth".equals(authName)) {
|
||||
auth = new OAuth(OAuthFlow.implicit, "http://petstore.swagger.io/api/oauth/dialog", "", "write:pets, read:pets");
|
||||
auth = buildOauthRequestInterceptor(OAuthFlow.implicit, "http://petstore.swagger.io/api/oauth/dialog", "", "write:pets, read:pets");
|
||||
} else {
|
||||
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
|
||||
}
|
||||
@ -78,34 +80,6 @@ public class ApiClient {
|
||||
this.setApiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for single basic auth or password oauth2
|
||||
* @param authName
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public ApiClient(String authName, String username, String password) {
|
||||
this(authName);
|
||||
this.setCredentials(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for single password oauth2
|
||||
* @param authName
|
||||
* @param clientId
|
||||
* @param secret
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public ApiClient(String authName, String clientId, String secret, String username, String password) {
|
||||
this(authName);
|
||||
this.getTokenEndPoint()
|
||||
.setClientId(clientId)
|
||||
.setClientSecret(secret)
|
||||
.setUsername(username)
|
||||
.setPassword(password);
|
||||
}
|
||||
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
@ -150,10 +124,25 @@ public class ApiClient {
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
private RequestInterceptor buildOauthRequestInterceptor(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
switch (flow) {
|
||||
case password:
|
||||
return new OauthPasswordGrant(tokenUrl, scopes);
|
||||
case application:
|
||||
return new OauthClientCredentialsGrant(authorizationUrl, tokenUrl, scopes);
|
||||
default:
|
||||
throw new RuntimeException("Oauth flow \"" + flow + "\" is not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectMapper getObjectMapper(){
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a feign client for given API interface.
|
||||
*
|
||||
@ -200,19 +189,13 @@ public class ApiClient {
|
||||
return contentTypes[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to configure the bearer token.
|
||||
* @param bearerToken the bearer token.
|
||||
*/
|
||||
public void setBearerToken(String bearerToken) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof HttpBearerAuth) {
|
||||
((HttpBearerAuth) apiAuthorization).setBearerToken(bearerToken);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No Bearer authentication configured!");
|
||||
HttpBearerAuth apiAuthorization = getAuthorization(HttpBearerAuth.class);
|
||||
apiAuthorization.setBearerToken(bearerToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,63 +203,38 @@ public class ApiClient {
|
||||
* @param apiKey API key
|
||||
*/
|
||||
public void setApiKey(String apiKey) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof ApiKeyAuth) {
|
||||
ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
|
||||
keyAuth.setApiKey(apiKey);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
ApiKeyAuth apiAuthorization = getAuthorization(ApiKeyAuth.class);
|
||||
apiAuthorization.setApiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the username/password for basic auth or password OAuth
|
||||
* Helper method to configure the username/password for basic auth
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public void setCredentials(String username, String password) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof HttpBasicAuth) {
|
||||
HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
|
||||
basicAuth.setCredentials(username, password);
|
||||
return;
|
||||
}
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No Basic authentication or OAuth configured!");
|
||||
HttpBasicAuth apiAuthorization = getAuthorization(HttpBasicAuth.class);
|
||||
apiAuthorization.setCredentials(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Token request builder
|
||||
* Helper method to configure the client credentials for Oauth
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public TokenRequestBuilder getTokenEndPoint() {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
return oauth.getTokenRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public void setClientCredentials(String clientId, String clientSecret) {
|
||||
OauthClientCredentialsGrant authorization = getAuthorization(OauthClientCredentialsGrant.class);
|
||||
authorization.configure(clientId, clientSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Authentication request builder
|
||||
* Helper method to configure the username/password for Oauth password grant
|
||||
* @param username Username
|
||||
* @param password Password
|
||||
*/
|
||||
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
return oauth.getAuthenticationRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public void setOauthPassword(String username, String password, String clientId, String clientSecret) {
|
||||
OauthPasswordGrant apiAuthorization = getAuthorization(OauthPasswordGrant.class);
|
||||
apiAuthorization.configure(username, password, clientId, clientSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,14 +242,9 @@ public class ApiClient {
|
||||
* @param accessToken Access Token
|
||||
* @param expiresIn Validity period in seconds
|
||||
*/
|
||||
public void setAccessToken(String accessToken, Long expiresIn) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.setAccessToken(accessToken, expiresIn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
public void setAccessToken(String accessToken, Integer expiresIn) {
|
||||
OAuth apiAuthorization = getAuthorization(OAuth.class);
|
||||
apiAuthorization.setAccessToken(accessToken, expiresIn);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -301,19 +254,7 @@ public class ApiClient {
|
||||
* @param redirectURI Redirect URI
|
||||
*/
|
||||
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.getTokenRequestBuilder()
|
||||
.setClientId(clientId)
|
||||
.setClientSecret(clientSecret)
|
||||
.setRedirectURI(redirectURI);
|
||||
oauth.getAuthenticationRequestBuilder()
|
||||
.setClientId(clientId)
|
||||
.setRedirectURI(redirectURI);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -321,13 +262,8 @@ public class ApiClient {
|
||||
* @param accessTokenListener Acesss token listener
|
||||
*/
|
||||
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
|
||||
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.registerAccessTokenListener(accessTokenListener);
|
||||
return;
|
||||
}
|
||||
}
|
||||
OAuth apiAuthorization = getAuthorization(OAuth.class);
|
||||
apiAuthorization.registerAccessTokenListener(accessTokenListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,4 +288,11 @@ public class ApiClient {
|
||||
feignBuilder.requestInterceptor(authorization);
|
||||
}
|
||||
|
||||
private <T extends RequestInterceptor> T getAuthorization(Class<T> type) {
|
||||
return (T) apiAuthorizations.values()
|
||||
.stream()
|
||||
.filter(requestInterceptor -> type.isAssignableFrom(requestInterceptor.getClass()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("No Oauth authentication or OAuth configured!"));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.api.DefaultApi20;
|
||||
import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor;
|
||||
import com.github.scribejava.core.extractors.TokenExtractor;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.oauth2.bearersignature.BearerSignature;
|
||||
import com.github.scribejava.core.oauth2.bearersignature.BearerSignatureURIQueryParameter;
|
||||
import com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication;
|
||||
import com.github.scribejava.core.oauth2.clientauthentication.RequestBodyAuthenticationScheme;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public class DefaultApi20Impl extends DefaultApi20 {
|
||||
|
||||
private final String accessTokenEndpoint;
|
||||
private final String authorizationBaseUrl;
|
||||
|
||||
protected DefaultApi20Impl(String authorizationBaseUrl, String accessTokenEndpoint) {
|
||||
this.authorizationBaseUrl = authorizationBaseUrl;
|
||||
this.accessTokenEndpoint = accessTokenEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTokenEndpoint() {
|
||||
return accessTokenEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAuthorizationBaseUrl() {
|
||||
return authorizationBaseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BearerSignature getBearerSignature() {
|
||||
return BearerSignatureURIQueryParameter.instance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientAuthentication getClientAuthentication() {
|
||||
return RequestBodyAuthenticationScheme.instance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenExtractor<OAuth2AccessToken> getAccessTokenExtractor() {
|
||||
return OAuth2AccessTokenJsonExtractor.instance();
|
||||
}
|
||||
}
|
@ -1,76 +1,34 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.oltu.oauth2.client.HttpClient;
|
||||
import org.apache.oltu.oauth2.client.OAuthClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
import org.apache.oltu.oauth2.common.token.BasicOAuthToken;
|
||||
|
||||
import feign.Client;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.oauth.OAuth20Service;
|
||||
import feign.Request.HttpMethod;
|
||||
import feign.Request.Options;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Response;
|
||||
import feign.RetryableException;
|
||||
import feign.Util;
|
||||
import org.openapitools.client.StringUtil;
|
||||
|
||||
|
||||
public class OAuth implements RequestInterceptor {
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public abstract class OAuth implements RequestInterceptor {
|
||||
|
||||
static final int MILLIS_PER_SECOND = 1000;
|
||||
|
||||
public interface AccessTokenListener {
|
||||
void notify(BasicOAuthToken token);
|
||||
void notify(OAuth2AccessToken token);
|
||||
}
|
||||
|
||||
private volatile String accessToken;
|
||||
private Long expirationTimeMillis;
|
||||
private OAuthClient oauthClient;
|
||||
private TokenRequestBuilder tokenRequestBuilder;
|
||||
private AuthenticationRequestBuilder authenticationRequestBuilder;
|
||||
private AccessTokenListener accessTokenListener;
|
||||
|
||||
public OAuth(Client client, TokenRequestBuilder requestBuilder) {
|
||||
this.oauthClient = new OAuthClient(new OAuthFeignClient(client));
|
||||
this.tokenRequestBuilder = requestBuilder;
|
||||
}
|
||||
protected OAuth20Service service;
|
||||
protected String scopes;
|
||||
protected String authorizationUrl;
|
||||
protected String tokenUrl;
|
||||
|
||||
public OAuth(Client client, OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this(client, OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
|
||||
|
||||
switch(flow) {
|
||||
case accessCode:
|
||||
case implicit:
|
||||
tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
|
||||
break;
|
||||
case password:
|
||||
tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
|
||||
break;
|
||||
case application:
|
||||
tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
|
||||
}
|
||||
|
||||
public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes);
|
||||
public OAuth(String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this.scopes = scopes;
|
||||
this.authorizationUrl = authorizationUrl;
|
||||
this.tokenUrl = tokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -88,21 +46,25 @@ public class OAuth implements RequestInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void updateAccessToken(RequestTemplate template) {
|
||||
OAuthJSONAccessTokenResponse accessTokenResponse;
|
||||
private synchronized void updateAccessToken(RequestTemplate template) {
|
||||
OAuth2AccessToken accessTokenResponse;
|
||||
try {
|
||||
accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
|
||||
accessTokenResponse = getOAuth2AccessToken();
|
||||
} catch (Exception e) {
|
||||
throw new RetryableException(0, e.getMessage(), HttpMethod.POST, e, null, template.request());
|
||||
}
|
||||
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
|
||||
setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn());
|
||||
if (accessTokenListener != null) {
|
||||
accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
|
||||
accessTokenListener.notify(accessTokenResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract OAuth2AccessToken getOAuth2AccessToken();
|
||||
|
||||
abstract OAuthFlow getFlow();
|
||||
|
||||
public synchronized void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
|
||||
this.accessTokenListener = accessTokenListener;
|
||||
}
|
||||
@ -111,88 +73,9 @@ public class OAuth implements RequestInterceptor {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public synchronized void setAccessToken(String accessToken, Long expiresIn) {
|
||||
public synchronized void setAccessToken(String accessToken, Integer expiresIn) {
|
||||
this.accessToken = accessToken;
|
||||
this.expirationTimeMillis = expiresIn == null ? null : System.currentTimeMillis() + expiresIn * MILLIS_PER_SECOND;
|
||||
}
|
||||
|
||||
public TokenRequestBuilder getTokenRequestBuilder() {
|
||||
return tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public AuthenticationRequestBuilder getAuthenticationRequestBuilder() {
|
||||
return authenticationRequestBuilder;
|
||||
}
|
||||
|
||||
public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) {
|
||||
this.authenticationRequestBuilder = authenticationRequestBuilder;
|
||||
}
|
||||
|
||||
public OAuthClient getOauthClient() {
|
||||
return oauthClient;
|
||||
}
|
||||
|
||||
public void setOauthClient(OAuthClient oauthClient) {
|
||||
this.oauthClient = oauthClient;
|
||||
}
|
||||
|
||||
public void setOauthClient(Client client) {
|
||||
this.oauthClient = new OAuthClient( new OAuthFeignClient(client));
|
||||
}
|
||||
|
||||
public static class OAuthFeignClient implements HttpClient {
|
||||
|
||||
private Client client;
|
||||
|
||||
public OAuthFeignClient() {
|
||||
this.client = new Client.Default(null, null);
|
||||
}
|
||||
|
||||
public OAuthFeignClient(Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
RequestTemplate req = new RequestTemplate()
|
||||
.append(request.getLocationUri())
|
||||
.method(requestMethod)
|
||||
.body(request.getBody());
|
||||
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
req.header(entry.getKey(), entry.getValue());
|
||||
}
|
||||
Response feignResponse;
|
||||
String body = "";
|
||||
try {
|
||||
feignResponse = client.execute(req.request(), new Options());
|
||||
body = Util.toString(feignResponse.body().asReader());
|
||||
} catch (IOException e) {
|
||||
throw new OAuthSystemException(e);
|
||||
}
|
||||
|
||||
String contentType = null;
|
||||
Collection<String> contentTypeHeader = feignResponse.headers().get("Content-Type");
|
||||
if(contentTypeHeader != null) {
|
||||
contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";");
|
||||
}
|
||||
|
||||
return OAuthClientResponseFactory.createCustomResponse(
|
||||
body,
|
||||
contentType,
|
||||
feignResponse.status(),
|
||||
responseClass
|
||||
);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public class OauthClientCredentialsGrant extends OAuth {
|
||||
|
||||
public OauthClientCredentialsGrant(String authorizationUrl, String tokenUrl, String scopes) {
|
||||
super(authorizationUrl, tokenUrl, scopes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2AccessToken getOAuth2AccessToken() {
|
||||
try {
|
||||
return service.getAccessTokenClientCredentialsGrant(scopes);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get oauth token", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuthFlow getFlow() {
|
||||
return OAuthFlow.application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the client credentials flow
|
||||
*
|
||||
* @param clientId
|
||||
* @param clientSecret
|
||||
*/
|
||||
public void configure(String clientId, String clientSecret) {
|
||||
service = new ServiceBuilder(clientId)
|
||||
.apiSecret(clientSecret)
|
||||
.defaultScope(scopes)
|
||||
.build(new DefaultApi20Impl(authorizationUrl, tokenUrl));
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public class OauthPasswordGrant extends OAuth {
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public OauthPasswordGrant(String tokenUrl, String scopes) {
|
||||
super(null, tokenUrl, scopes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2AccessToken getOAuth2AccessToken() {
|
||||
try {
|
||||
return service.getAccessTokenPasswordGrant(username, password);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get oauth token", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuthFlow getFlow() {
|
||||
return OAuthFlow.password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Oauth password grant flow
|
||||
* Note: this flow is deprecated.
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @param clientId
|
||||
* @param clientSecret
|
||||
*/
|
||||
public void configure(String username, String password, String clientId, String clientSecret) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
//TODO the clientId and secret are optional according with the RFC
|
||||
service = new ServiceBuilder(clientId)
|
||||
.apiSecret(clientSecret)
|
||||
.defaultScope(scopes)
|
||||
.build(new DefaultApi20Impl(authorizationUrl, tokenUrl));
|
||||
}
|
||||
}
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
accessCode, //called authorizationCode in OpenAPI 3.0
|
||||
implicit,
|
||||
password,
|
||||
application //called clientCredentials in OpenAPI 3.0
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user