BearerTokenStrategy.java
package com.guinetik.rr.auth;
import com.guinetik.rr.http.RocketHeaders;
import java.util.function.BooleanSupplier;
/**
* Authentication strategy that uses Bearer token authentication.
*
* <p>This strategy adds an {@code Authorization: Bearer <token>} header to all requests.
* It's suitable for APIs that use API keys, JWT tokens, or other bearer-style authentication.
*
* <h2>Basic Usage</h2>
* <pre class="language-java"><code>
* // Create via factory (recommended)
* AuthStrategy auth = AuthStrategyFactory.createBearerToken("my-api-token");
*
* // Configure client
* RocketRestConfig config = RocketRestConfig.builder("https://api.example.com")
* .authStrategy(auth)
* .build();
* </code></pre>
*
* <h2>With Custom Refresh Logic</h2>
* <p>For tokens that expire, you can provide custom refresh logic:
* <pre class="language-java"><code>
* AtomicReference<String> tokenRef = new AtomicReference<>("initial-token");
*
* AuthStrategy auth = AuthStrategyFactory.createBearerToken(tokenRef.get(), () -> {
* try {
* String newToken = myAuthService.refreshToken();
* tokenRef.set(newToken);
* return true;
* } catch (Exception e) {
* return false;
* }
* });
* </code></pre>
*
* <h2>For OAuth Tokens</h2>
* <p>If your bearer token comes from an OAuth flow, consider using the dedicated OAuth strategies
* which handle token refresh automatically:
* <ul>
* <li>{@link OAuth2ClientCredentialsStrategy}</li>
* <li>{@link OAuth2PasswordStrategy}</li>
* <li>{@link OAuth2AssertionStrategy}</li>
* </ul>
*
* @author guinetik <guinetik@gmail.com>
* @see AuthStrategy
* @see AuthStrategyFactory#createBearerToken(String)
* @since 1.0.0
*/
public class BearerTokenStrategy implements AuthStrategy {
private final String token;
private final BooleanSupplier refreshTokenLogic;
/**
* Creates a new BearerTokenStrategy with no custom refresh logic.
* In this case, {@link #refreshCredentials()} will always return {@code false}.
*
* @param token the bearer token
*/
public BearerTokenStrategy(String token) {
this(token, () -> false);
}
/**
* Creates a new BearerTokenStrategy with custom token refresh logic.
*
* @param token the bearer token
* @param refreshTokenLogic a {@link BooleanSupplier} that will be invoked by {@link #refreshCredentials()}.
* It should return {@code true} if the token was successfully refreshed, {@code false} otherwise.
*/
public BearerTokenStrategy(String token, BooleanSupplier refreshTokenLogic) {
this.token = token;
this.refreshTokenLogic = refreshTokenLogic != null ? refreshTokenLogic : () -> false;
}
@Override
public AuthType getType() {
return AuthType.BEARER_TOKEN;
}
@Override
public RocketHeaders applyAuthHeaders(RocketHeaders headers) {
if (token != null && !token.isEmpty()) {
headers.bearerAuth(token);
}
return headers;
}
@Override
public boolean needsTokenRefresh() {
return false;
}
/**
* {@inheritDoc}
* <p>
* If a custom {@code refreshTokenLogic} was provided during construction,
* this method will invoke it and return its result.
* <p>
* If no custom logic was provided, this method always returns {@code false},
* as this strategy itself does not handle credential refresh.
*/
@Override
public boolean refreshCredentials() {
return this.refreshTokenLogic.getAsBoolean();
}
}