Java.libraries.feign.auth.OAuth.mustache Maven / Gradle / Ivy
package {{invokerPackage}}.auth;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.oauth.OAuth20Service;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import java.util.Collection;
{{>generatedAnnotation}}
public abstract class OAuth implements RequestInterceptor {
//https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4
static final int LEEWAY_SECONDS = 10;
static final int MILLIS_PER_SECOND = 1000;
public interface AccessTokenListener {
void notify(OAuth2AccessToken token);
}
private volatile String accessToken;
private Long expirationTimeSeconds;
private AccessTokenListener accessTokenListener;
protected OAuth20Service service;
protected String scopes;
protected String authorizationUrl;
protected String tokenUrl;
public OAuth(String authorizationUrl, String tokenUrl, String scopes) {
this.scopes = scopes;
this.authorizationUrl = authorizationUrl;
this.tokenUrl = tokenUrl;
}
@Override
public void apply(RequestTemplate template) {
// If the request already have an authorization (eg. Basic auth), do nothing
if (requestContainsNonOauthAuthorization(template)) {
return;
}
String accessToken = getAccessToken();
if (accessToken != null) {
template.removeHeader("Authorization");
template.header("Authorization", "Bearer " + accessToken);
}
}
private boolean requestContainsNonOauthAuthorization(RequestTemplate template) {
Collection authorizations = template.headers().get("Authorization");
if (authorizations == null) {
return false;
}
return !authorizations.stream()
.anyMatch(authHeader -> !authHeader.equalsIgnoreCase("Bearer"));
}
private synchronized void updateAccessToken() {
OAuth2AccessToken accessTokenResponse;
accessTokenResponse = getOAuth2AccessToken();
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn());
if (accessTokenListener != null) {
accessTokenListener.notify(accessTokenResponse);
}
}
}
abstract OAuth2AccessToken getOAuth2AccessToken();
abstract OAuthFlow getFlow();
public synchronized void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
this.accessTokenListener = accessTokenListener;
}
public synchronized String getAccessToken() {
// If first time, get the token
if (expirationTimeSeconds == null || System.currentTimeMillis() >= expirationTimeSeconds * MILLIS_PER_SECOND) {
updateAccessToken();
}
return accessToken;
}
/**
* Manually sets the access token
* @param accessToken The access token
* @param expiresIn Seconds until the token expires
*/
public synchronized void setAccessToken(String accessToken, Integer expiresIn) {
this.accessToken = accessToken;
this.expirationTimeSeconds = expiresIn == null ? null : System.currentTimeMillis() / MILLIS_PER_SECOND + expiresIn - LEEWAY_SECONDS;
}
}