github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/java/libraries/okhttp-gson/auth/RetryingOAuth.mustache (about) 1 {{#hasOAuthMethods}} 2 package {{invokerPackage}}.auth; 3 4 import {{invokerPackage}}.Pair; 5 6 import okhttp3.Interceptor; 7 import okhttp3.OkHttpClient; 8 import okhttp3.Request; 9 import okhttp3.Response; 10 11 import org.apache.oltu.oauth2.client.OAuthClient; 12 import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest; 13 import org.apache.oltu.oauth2.client.request.OAuthClientRequest; 14 import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; 15 import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse; 16 import org.apache.oltu.oauth2.common.exception.OAuthProblemException; 17 import org.apache.oltu.oauth2.common.exception.OAuthSystemException; 18 import org.apache.oltu.oauth2.common.message.types.GrantType; 19 20 import java.io.IOException; 21 import java.net.HttpURLConnection; 22 import java.util.Map; 23 import java.util.List; 24 25 public class RetryingOAuth extends OAuth implements Interceptor { 26 private OAuthClient oAuthClient; 27 28 private TokenRequestBuilder tokenRequestBuilder; 29 30 public RetryingOAuth(OkHttpClient client, TokenRequestBuilder tokenRequestBuilder) { 31 this.oAuthClient = new OAuthClient(new OAuthOkHttpClient(client)); 32 this.tokenRequestBuilder = tokenRequestBuilder; 33 } 34 35 public RetryingOAuth(TokenRequestBuilder tokenRequestBuilder) { 36 this(new OkHttpClient(), tokenRequestBuilder); 37 } 38 39 /** 40 @param tokenUrl The token URL to be used for this OAuth2 flow. 41 Applicable to the following OAuth2 flows: "password", "clientCredentials" and "authorizationCode". 42 The value must be an absolute URL. 43 @param clientId The OAuth2 client ID for the "clientCredentials" flow. 44 @param clientSecret The OAuth2 client secret for the "clientCredentials" flow. 45 */ 46 public RetryingOAuth( 47 String tokenUrl, 48 String clientId, 49 OAuthFlow flow, 50 String clientSecret, 51 Map<String, String> parameters 52 ) { 53 this(OAuthClientRequest.tokenLocation(tokenUrl) 54 .setClientId(clientId) 55 .setClientSecret(clientSecret)); 56 setFlow(flow); 57 if (parameters != null) { 58 for (String paramName : parameters.keySet()) { 59 tokenRequestBuilder.setParameter(paramName, parameters.get(paramName)); 60 } 61 } 62 } 63 64 public void setFlow(OAuthFlow flow) { 65 switch(flow) { 66 case accessCode: 67 tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE); 68 break; 69 case implicit: 70 tokenRequestBuilder.setGrantType(GrantType.IMPLICIT); 71 break; 72 case password: 73 tokenRequestBuilder.setGrantType(GrantType.PASSWORD); 74 break; 75 case application: 76 tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS); 77 break; 78 default: 79 break; 80 } 81 } 82 83 @Override 84 public Response intercept(Chain chain) throws IOException { 85 return retryingIntercept(chain, true); 86 } 87 88 private Response retryingIntercept(Chain chain, boolean updateTokenAndRetryOnAuthorizationFailure) throws IOException { 89 Request request = chain.request(); 90 91 // If the request already has an authorization (e.g. Basic auth), proceed with the request as is 92 if (request.header("Authorization") != null) { 93 return chain.proceed(request); 94 } 95 96 // Get the token if it has not yet been acquired 97 if (getAccessToken() == null) { 98 updateAccessToken(null); 99 } 100 101 OAuthClientRequest oAuthRequest; 102 if (getAccessToken() != null) { 103 // Build the request 104 Request.Builder requestBuilder = request.newBuilder(); 105 106 String requestAccessToken = getAccessToken(); 107 try { 108 oAuthRequest = 109 new OAuthBearerClientRequest(request.url().toString()). 110 setAccessToken(requestAccessToken). 111 buildHeaderMessage(); 112 } catch (OAuthSystemException e) { 113 throw new IOException(e); 114 } 115 116 Map<String, String> headers = oAuthRequest.getHeaders(); 117 for (String headerName : headers.keySet()) { 118 requestBuilder.addHeader(headerName, headers.get(headerName)); 119 } 120 requestBuilder.url(oAuthRequest.getLocationUri()); 121 122 // Execute the request 123 Response response = chain.proceed(requestBuilder.build()); 124 125 // 401/403 response codes most likely indicate an expired access token, unless it happens two times in a row 126 if ( 127 response != null && 128 ( response.code() == HttpURLConnection.HTTP_UNAUTHORIZED || 129 response.code() == HttpURLConnection.HTTP_FORBIDDEN ) && 130 updateTokenAndRetryOnAuthorizationFailure 131 ) { 132 try { 133 if (updateAccessToken(requestAccessToken)) { 134 response.body().close(); 135 return retryingIntercept(chain, false); 136 } 137 } catch (Exception e) { 138 response.body().close(); 139 throw e; 140 } 141 } 142 return response; 143 } 144 else { 145 return chain.proceed(chain.request()); 146 } 147 } 148 149 /* 150 * Returns true if the access token has been updated 151 */ 152 public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException { 153 if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) { 154 try { 155 OAuthJSONAccessTokenResponse accessTokenResponse = 156 oAuthClient.accessToken(tokenRequestBuilder.buildBodyMessage()); 157 if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) { 158 setAccessToken(accessTokenResponse.getAccessToken()); 159 return !getAccessToken().equals(requestAccessToken); 160 } 161 } catch (OAuthSystemException | OAuthProblemException e) { 162 throw new IOException(e); 163 } 164 } 165 166 return false; 167 } 168 169 public TokenRequestBuilder getTokenRequestBuilder() { 170 return tokenRequestBuilder; 171 } 172 173 public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) { 174 this.tokenRequestBuilder = tokenRequestBuilder; 175 } 176 177 // Applying authorization to parameters is performed in the retryingIntercept method 178 @Override 179 public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams) { 180 // No implementation necessary 181 } 182 } 183 {{/hasOAuthMethods}}