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

com.microsoft.kiota.authentication.ApiKeyAuthenticationProvider Maven / Gradle / Ivy

package com.microsoft.kiota.authentication;

import com.microsoft.kiota.RequestInformation;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.Objects;

/** This authentication provider adds an API key to the request as a query parameter or header. */
public class ApiKeyAuthenticationProvider implements AuthenticationProvider {
    private final ApiKeyLocation location;
    @Nonnull private final String paramName;
    @Nonnull private final String apiKey;
    private final AllowedHostsValidator validator;

    /**
     * Creates a new instance of ApiKeyAuthenticationProvider.
     * @param apiKey The API key to use.
     * @param paramName The name of the query parameter or header to use.
     * @param location The location of the API key.
     * @param validHosts The list of allowed hosts for which to add the API key.
     */
    public ApiKeyAuthenticationProvider(
            @Nonnull final String apiKey,
            @Nonnull final String paramName,
            @Nonnull final ApiKeyLocation location,
            @Nonnull final String... validHosts) {
        Objects.requireNonNull(apiKey);
        Objects.requireNonNull(paramName);
        Objects.requireNonNull(location);
        if (apiKey.isEmpty()) {
            throw new IllegalArgumentException("apiKey cannot be empty");
        }
        if (paramName.isEmpty()) {
            throw new IllegalArgumentException("paramName cannot be empty");
        }
        this.apiKey = apiKey;
        this.paramName = paramName;
        this.location = location;
        this.validator = new AllowedHostsValidator(validHosts);
    }

    private static final String parentSpanKey = "parent-span";

    /** {@inheritDoc} */
    @Override
    public void authenticateRequest(
            @Nonnull final RequestInformation request,
            @Nullable final Map additionalAuthenticationContext) {
        Objects.requireNonNull(request);
        Span span;
        if (additionalAuthenticationContext != null
                && additionalAuthenticationContext.containsKey(parentSpanKey)
                && additionalAuthenticationContext.get(parentSpanKey) instanceof Span) {
            final Span parentSpan = (Span) additionalAuthenticationContext.get(parentSpanKey);
            span =
                    GlobalOpenTelemetry.getTracer("com.microsoft.kiota")
                            .spanBuilder("authenticateRequest")
                            .setParent(Context.current().with(parentSpan))
                            .startSpan();
        } else {
            span =
                    GlobalOpenTelemetry.getTracer("com.microsoft.kiota")
                            .spanBuilder("authenticateRequest")
                            .startSpan();
        }
        try (final Scope scope = span.makeCurrent()) {
            final URI uri = request.getUri();
            if (uri == null || !validator.isUrlHostValid(uri)) {
                span.setAttribute("com.microsoft.kiota.authentication.is_url_valid", false);
                return;
            }
            if (!uri.getScheme().equalsIgnoreCase("https")) {
                span.setAttribute("com.microsoft.kiota.authentication.is_url_valid", false);
                throw new IllegalArgumentException("Only https is supported");
            }
            span.setAttribute("com.microsoft.kiota.authentication.is_url_valid", true);

            switch (location) {
                case HEADER:
                    request.headers.add(paramName, apiKey);
                    break;
                case QUERY_PARAMETER:
                    request.setUri(
                            new URI(
                                    uri.getScheme(),
                                    uri.getAuthority(),
                                    uri.getPath(),
                                    uri.getQuery() == null
                                            ? paramName + "=" + apiKey
                                            : uri.getQuery() + "&" + paramName + "=" + apiKey,
                                    uri.getFragment()));
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported key location");
            }
        } catch (URISyntaxException e) {
            span.recordException(e);
            throw new RuntimeException("Malformed URI", e);
        } catch (IllegalArgumentException e) {
            span.recordException(e);
            throw e;
        } finally {
            span.end();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy