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

io.camunda.identity.sdk.impl.auth0.authentication.Auth0Authentication Maven / Gradle / Ivy

There is a newer version: 8.5.9
Show newest version
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
 * one or more contributor license agreements. Licensed under a proprietary license. See the
 * License.txt file for more information. You may not use this file except in compliance with the
 * proprietary license.
 */

package io.camunda.identity.sdk.impl.auth0.authentication;

import com.auth0.client.auth.AuthAPI;
import com.auth0.exception.Auth0Exception;
import com.auth0.json.auth.TokenHolder;
import com.auth0.jwk.JwkProvider;
import com.auth0.jwk.JwkProviderBuilder;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.net.AuthRequest;
import com.auth0.net.Request;
import com.auth0.net.TokenRequest;
import io.camunda.identity.sdk.IdentityConfiguration;
import io.camunda.identity.sdk.authentication.AbstractAuthentication;
import io.camunda.identity.sdk.authentication.AuthorizeUriBuilder;
import io.camunda.identity.sdk.authentication.Tokens;
import io.camunda.identity.sdk.authentication.dto.AuthCodeDto;
import io.camunda.identity.sdk.authentication.dto.OrganizationDto;
import io.camunda.identity.sdk.authentication.exception.CodeExchangeException;
import io.camunda.identity.sdk.exception.IdentityException;
import io.camunda.identity.sdk.impl.dto.WellKnownConfiguration;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.Validate;

public class Auth0Authentication extends AbstractAuthentication {
  private AuthAPI authApi;
  private JwkProvider jwkProvider;

  public Auth0Authentication(final IdentityConfiguration configuration) {
    super(configuration);
  }

  private AuthAPI authApi() {
    if (authApi == null) {
      authApi = new AuthAPI(configuration.getIssuer(), configuration.getClientId(),
                            configuration.getClientSecret());
    }
    return authApi;
  }

  @Override
  public AuthorizeUriBuilder authorizeUriBuilder(final String redirectUri) {
    return new Auth0AuthorizeUriBuilder(configuration, authApi(), redirectUri);
  }

  @Override
  public Tokens exchangeAuthCode(
      final AuthCodeDto authCodeDto,
      final String redirectUri
  ) throws CodeExchangeException {
    Validate.notNull(authCodeDto, "authCodeDto must not be null");
    Validate.notNull(redirectUri, "redirectUri must not be null");

    if (authCodeDto.getError() != null && !authCodeDto.getError().isBlank()) {
      throw new CodeExchangeException(authCodeDto.getError());
    }

    final AuthRequest request = authApi().exchangeCode(authCodeDto.getCode(), redirectUri)
        .setAudience(configuration.getAudience());
    try {
      final TokenHolder tokenHolder = request.execute();
      return fromTokenHolder(tokenHolder);
    } catch (final Auth0Exception exception) {
      throw new CodeExchangeException("Auth0 Code exchange failed", exception);
    }
  }

  @Override
  protected Tokens requestFreshToken(final String audience) {
    final TokenRequest request = authApi().requestToken(audience);

    try {
      final TokenHolder tokenHolder = request.execute();
      return fromTokenHolder(tokenHolder);
    } catch (final Auth0Exception exception) {
      throw new IdentityException("Auth0 token request failed", exception);
    }
  }

  @Override
  public Tokens renewToken(final String refreshToken) {
    Validate.notEmpty(refreshToken, "refreshToken can not be empty");

    final TokenRequest request = authApi().renewAuth(refreshToken);
    try {
      final TokenHolder tokenHolder = request.execute();
      return fromTokenHolder(tokenHolder);
    } catch (final Auth0Exception exception) {
      throw new IdentityException("Auth0 refresh failed", exception);
    }
  }

  @Override
  public void revokeToken(final String refreshToken) {
    final Request request = authApi().revokeToken(refreshToken);
    try {
      request.execute();
    } catch (final Auth0Exception exception) {
      throw new IdentityException("Auth0 token revocation failed", exception);
    }
  }

  @Override
  public boolean isM2MToken(final String token) {
    final DecodedJWT decodedJwt = decodeJWT(token);
    final Claim subClaim = decodedJwt.getClaim("sub");

    return subClaim.asString().contains("@clients");
  }

  @Override
  public String getClientId(final String token) {
    final DecodedJWT decodedJwt = decodeJWT(token);
    return decodedJwt.getClaim("azp").asString();
  }

  @Override
  protected List getPermissions(final DecodedJWT token, final String audience) {
    var permissionsClaim = token.getClaim("permissions");
    if (permissionsClaim.isMissing()) {
      return Collections.emptyList();
    }

    return permissionsClaim.asList(String.class);
  }

  @Override
  protected List getGroups(final DecodedJWT token) {
    return Collections.emptyList();
  }

  @Override
  protected Map> getAssignedOrganizations(final DecodedJWT token) {
    var orgClaim = token.getClaim("https://camunda.com/orgs");

    if (orgClaim.isMissing()) {
      return Collections.emptyMap();
    }

    return orgClaim.asList(OrganizationDto.class).stream()
        .collect(Collectors.toMap(OrganizationDto::getId, OrganizationDto::getRoles));
  }

  @Override
  protected JwkProvider jwkProvider() {
    if (jwkProvider == null) {
      jwkProvider = new JwkProviderBuilder(configuration.getIssuer())
          .cached(JWKS_CACHE_SIZE, JWKS_CACHE_LIFETIME_DAYS, TimeUnit.DAYS)
          .build();
    }
    return jwkProvider;
  }

  @Override
  protected WellKnownConfiguration wellKnownConfiguration() {
    throw new NotImplementedException();
  }

  private Tokens fromTokenHolder(final TokenHolder tokenHolder) {
    return new Tokens(tokenHolder.getAccessToken(),
                      tokenHolder.getRefreshToken(),
                      tokenHolder.getExpiresIn(),
                      tokenHolder.getScope(),
                      tokenHolder.getTokenType());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy