All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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