io.scalecube.services.security.ServiceTokenAuthenticator Maven / Gradle / Ivy
package io.scalecube.services.security;
import io.scalecube.security.tokens.jwt.JwtTokenResolver;
import io.scalecube.services.auth.Authenticator;
import io.scalecube.services.exceptions.UnauthorizedException;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import reactor.util.retry.Retry;
/**
* Implementation of {@link Authenticator} backed by {@link JwtTokenResolver}. Using {@code
* tokenResolver} (and {@code authDataMapper}) this authenticator turns extracted (and verified)
* source auth data into client specified destination auth data.
*/
public final class ServiceTokenAuthenticator implements Authenticator {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTokenAuthenticator.class);
private JwtTokenResolver tokenResolver;
private ServiceTokenMapper tokenMapper;
private AuthDataMapper authDataMapper;
private Retry retryStrategy = RetryStrategies.noRetriesRetryStrategy();
public ServiceTokenAuthenticator() {}
private ServiceTokenAuthenticator(ServiceTokenAuthenticator other) {
this.tokenResolver = other.tokenResolver;
this.tokenMapper = other.tokenMapper;
this.authDataMapper = other.authDataMapper;
this.retryStrategy = other.retryStrategy;
}
private ServiceTokenAuthenticator copy() {
return new ServiceTokenAuthenticator<>(this);
}
/**
* Setter for tokenResolver.
*
* @param tokenResolver tokenResolver
* @return new instance with applied setting
*/
public ServiceTokenAuthenticator tokenResolver(JwtTokenResolver tokenResolver) {
final ServiceTokenAuthenticator c = copy();
c.tokenResolver = tokenResolver;
return c;
}
/**
* Setter for tokenMapper.
*
* @param tokenMapper tokenMapper
* @return new instance with applied setting
*/
public ServiceTokenAuthenticator tokenMapper(ServiceTokenMapper tokenMapper) {
final ServiceTokenAuthenticator c = copy();
c.tokenMapper = tokenMapper;
return c;
}
/**
* Setter for authDataMapper.
*
* @param authDataMapper authDataMapper
* @return new instance with applied setting
*/
public ServiceTokenAuthenticator authDataMapper(AuthDataMapper authDataMapper) {
final ServiceTokenAuthenticator c = copy();
c.authDataMapper = authDataMapper;
return c;
}
/**
* Setter for retryStrategy.
*
* @param retryStrategy retryStrategy
* @return new instance with applied setting
*/
public ServiceTokenAuthenticator retryStrategy(Retry retryStrategy) {
final ServiceTokenAuthenticator c = copy();
c.retryStrategy = retryStrategy;
return c;
}
@Override
public Mono apply(Map credentials) {
return Mono.defer(
() -> {
String serviceToken = tokenMapper.map(credentials);
if (serviceToken == null) {
throw new UnauthorizedException("Authentication failed");
}
return tokenResolver
.resolve(serviceToken)
.map(authDataMapper::map)
.retryWhen(retryStrategy)
.doOnError(th -> LOGGER.error("Failed to authenticate, cause: {}", th.toString()))
.onErrorMap(th -> new UnauthorizedException("Authentication failed"))
.switchIfEmpty(Mono.error(new UnauthorizedException("Authentication failed")));
});
}
@FunctionalInterface
public interface ServiceTokenMapper {
/**
* Returns service token from input credentials.
*
* @param credentials credentials (which must contain service token)
* @return extracted service token
*/
String map(Map credentials);
}
@FunctionalInterface
public interface AuthDataMapper {
/**
* Converts source auth data to the destination auth data.
*
* @param authData source auth data
* @return converted auth data
*/
A map(Map authData);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy