Package org.platformlayer.auth.system

Source Code of org.platformlayer.auth.system.PlatformLayerAuthAdminClient

package org.platformlayer.auth.system;

import java.security.cert.X509Certificate;
import java.util.List;

import javax.inject.Inject;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;

import org.platformlayer.WellKnownPorts;
import org.platformlayer.auth.AuthenticationToken;
import org.platformlayer.auth.AuthenticationTokenValidator;
import org.platformlayer.auth.PlatformlayerAuthenticationToken;
import org.platformlayer.auth.v1.CertificateChainInfo;
import org.platformlayer.auth.v1.CheckServiceAccessRequest;
import org.platformlayer.auth.v1.CheckServiceAccessResponse;
import org.platformlayer.auth.v1.ProjectValidation;
import org.platformlayer.auth.v1.Role;
import org.platformlayer.auth.v1.SignCertificateRequest;
import org.platformlayer.auth.v1.SignCertificateResponse;
import org.platformlayer.auth.v1.UserValidation;
import org.platformlayer.auth.v1.ValidateAccess;
import org.platformlayer.auth.v1.ValidateTokenResponse;
import org.platformlayer.crypto.CertificateUtils;
import org.platformlayer.http.HttpMethod;
import org.platformlayer.http.HttpStrategy;
import org.platformlayer.http.SslConfiguration;
import org.platformlayer.http.UrlUtils;
import org.platformlayer.model.ProjectAuthorization;
import org.platformlayer.model.RoleId;
import org.platformlayer.ops.OpsException;
import org.platformlayer.rest.HttpPayload;
import org.platformlayer.rest.JreRestfulClient;
import org.platformlayer.rest.RestClientException;
import org.platformlayer.rest.RestfulClient;
import org.platformlayer.rest.RestfulRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fathomdb.Configuration;
import com.fathomdb.crypto.CertificateAndKey;
import com.fathomdb.crypto.CryptoKey;
import com.fathomdb.crypto.EncryptionStore;
import com.fathomdb.crypto.FathomdbCrypto;
import com.fathomdb.crypto.SimpleClientCertificateKeyManager;
import com.fathomdb.crypto.ssl.AcceptAllHostnameVerifier;
import com.fathomdb.crypto.ssl.PublicKeyTrustManager;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;

public class PlatformLayerAuthAdminClient implements AuthenticationTokenValidator {
  static final Logger log = LoggerFactory.getLogger(PlatformLayerAuthAdminClient.class);

  public static final String DEFAULT_AUTHENTICATION_URL = "https://127.0.0.1:"
      + WellKnownPorts.PORT_PLATFORMLAYER_AUTH_ADMIN + "/";

  final RestfulClient restfulClient;

  private PlatformLayerAuthAdminClient(RestfulClient restfulClient) {
    this.restfulClient = restfulClient;
  }

  public static AuthenticationTokenValidator build(HttpStrategy httpStrategy, Configuration configuration,
      EncryptionStore encryptionStore) throws OpsException {
    String keystoneServiceUrl = configuration.lookup("auth.system.url", "https://127.0.0.1:"
        + WellKnownPorts.PORT_PLATFORMLAYER_AUTH_ADMIN + "/");

    String cert = configuration.get("auth.system.tls.clientcert");

    CertificateAndKey certificateAndKey = encryptionStore.getCertificateAndKey(cert);

    HostnameVerifier hostnameVerifier = null;

    KeyManager keyManager = new SimpleClientCertificateKeyManager(certificateAndKey);

    TrustManager trustManager = null;

    String trustKeys = configuration.lookup("auth.system.ssl.keys", null);

    if (trustKeys != null) {
      trustManager = new PublicKeyTrustManager(Splitter.on(',').trimResults().split(trustKeys));

      hostnameVerifier = new AcceptAllHostnameVerifier();
    }

    if (log.isDebugEnabled() && certificateAndKey != null) {
      X509Certificate[] chain = certificateAndKey.getCertificateChain();
      log.debug("Using client cert for PL auth: " + Joiner.on(",").join(chain));
    }

    SslConfiguration sslConfiguration = new SslConfiguration(keyManager, trustManager, hostnameVerifier);
    RestfulClient restfulClient = new JreRestfulClient(httpStrategy, keystoneServiceUrl, sslConfiguration);

    AuthenticationTokenValidator tokenValidator = new PlatformLayerAuthAdminClient(restfulClient);
    tokenValidator = new CachingAuthenticationTokenValidator(tokenValidator);
    return tokenValidator;
  }

  @Override
  public ProjectAuthorization validateToken(AuthenticationToken authToken, String projectId) {
    // v2.0/tokens/{userToken}[?project={tenant}]

    String tokenId = ((PlatformlayerAuthenticationToken) authToken).getAuthTokenValue();
    tokenId = tokenId.trim();

    String url = "v2.0/tokens/" + tokenId;

    url += "?project=" + UrlUtils.urlEncode(projectId);

    try {
      ValidateTokenResponse response = doSimpleXmlRequest(HttpMethod.GET, url, null, ValidateTokenResponse.class);

      ValidateAccess access = response.getAccess();
      if (access == null) {
        return null;
      }

      // ProjectValidation project = access.getProject();
      // if (project == null || !Objects.equal(projectId, project.getId())) {
      // return null;
      // }

      UserValidation userInfo = access.getUser();
      if (userInfo == null) {
        return null;
      }

      ProjectValidation projectInfo = access.getProject();
      if (projectInfo == null) {
        return null;
      }

      // List<String> roles = Lists.newArrayList();
      // UserValidation userInfo = access.getUser();
      // for (Role role : userInfo.getRoles()) {
      // if (!role.getTenantId().equals(projectId)) {
      // throw new IllegalStateException("Tenant mismatch: " + role.getTenantId() + " vs " + projectId);
      // }
      // roles.add(role.getName());
      // }

      // byte[] userSecret = userInfo.getSecret();
      String userKey = userInfo.getName();

      PlatformlayerUserAuthentication user = new PlatformlayerUserAuthentication(authToken, userKey);
      PlatformlayerProjectAuthorization project = buildPlatformlayerProjectAuthorization(user, projectInfo);
      return project;
    } catch (RestClientException e) {
      if (e.getHttpResponseCode() != null && e.getHttpResponseCode() == 404) {
        // Not found => invalid token
        return null;
      }
      log.warn("Error while validating token", e);
      throw new IllegalArgumentException("Error while validating token", e);
    }
  }

  @Override
  public ProjectAuthorization validateChain(X509Certificate[] chain, String projectKey) {
    // v2.0/keychain[?project={projectKey}]

    String url = "v2.0/keychain";

    url += "?project=" + UrlUtils.urlEncode(projectKey);

    CertificateChainInfo chainInfo = CertificateChains.toModel(chain);

    try {
      ValidateTokenResponse response = doSimpleXmlRequest(HttpMethod.POST, url, chainInfo,
          ValidateTokenResponse.class);

      ValidateAccess access = response.getAccess();
      if (access == null) {
        return null;
      }

      UserValidation userInfo = access.getUser();
      if (userInfo == null) {
        return null;
      }

      ProjectValidation projectInfo = access.getProject();
      if (projectInfo == null) {
        return null;
      }

      String userKey = userInfo.getName();

      PlatformlayerUserAuthentication user = new PlatformlayerUserAuthentication(null, userKey);
      PlatformlayerProjectAuthorization project = buildPlatformlayerProjectAuthorization(user, projectInfo);
      return project;
    } catch (RestClientException e) {
      if (e.getHttpResponseCode() != null && e.getHttpResponseCode() == 404) {
        // Not found => invalid token
        return null;
      }
      log.warn("Error while validating credentials", e);
      throw new IllegalArgumentException("Error while validating credentials", e);
    }
  }

  private PlatformlayerProjectAuthorization buildPlatformlayerProjectAuthorization(
      PlatformlayerUserAuthentication user, ProjectValidation project) {

    String name = project.getName();
    int projectId = Integer.parseInt(project.getId());

    List<RoleId> roles = Lists.newArrayList();
    for (Role role : project.getRoles()) {
      roles.add(new RoleId(role.getName()));
    }

    CryptoKey projectSecret = FathomdbCrypto.deserializeKey(project.getSecret());
    return new PlatformlayerProjectAuthorization(user, name, projectSecret, roles, projectId);
  }

  // This can actually be moved to the user-auth system
  public List<X509Certificate> signCsr(String projectKey, CryptoKey projectSecret, String csr) {
    String url = "pki/csr";

    SignCertificateRequest request = new SignCertificateRequest();
    request.setProject(projectKey);
    request.setCsr(csr);
    request.setProjectSecret(FathomdbCrypto.serialize(projectSecret));

    try {
      SignCertificateResponse response = doSimpleXmlRequest(HttpMethod.POST, url, request,
          SignCertificateResponse.class);

      List<X509Certificate> certificates = Lists.newArrayList();
      for (String cert : response.getCertificates()) {
        certificates.addAll(CertificateUtils.fromPem(cert));
      }

      return certificates;
    } catch (RestClientException e) {
      throw new IllegalArgumentException("Error while signing certificate", e);
    }
  }

  public String checkServiceAccess(CertificateChainInfo chain) {
    String url = "services/check";

    CheckServiceAccessRequest request = new CheckServiceAccessRequest();
    request.setChain(chain);

    try {
      CheckServiceAccessResponse response = doSimpleXmlRequest(HttpMethod.POST, url, request,
          CheckServiceAccessResponse.class);

      return response.getServiceAccount();
    } catch (RestClientException e) {
      throw new IllegalArgumentException("Error while checking service access", e);
    }
  }

  protected <T> T doSimpleXmlRequest(HttpMethod method, String relativeUri, Object postObject, Class<T> responseClass)
      throws RestClientException {
    HttpPayload payload = postObject != null ? HttpPayload.asXml(postObject) : null;
    RestfulRequest<T> request = restfulClient.buildRequest(method, relativeUri, payload, responseClass);
    return request.execute();
  }

  public static PlatformLayerAuthAdminClient find(AuthenticationTokenValidator authenticationTokenValidator) {
    if (authenticationTokenValidator instanceof PlatformLayerAuthAdminClient) {
      return (PlatformLayerAuthAdminClient) authenticationTokenValidator;
    }
    if (authenticationTokenValidator instanceof CachingAuthenticationTokenValidator) {
      return find(((CachingAuthenticationTokenValidator) authenticationTokenValidator).getInner());
    }
    throw new IllegalArgumentException();
  }

  public static class Provider implements javax.inject.Provider<AuthenticationTokenValidator> {
    @Inject
    HttpStrategy httpStrategy;

    @Inject
    Configuration configuration;

    @Inject
    EncryptionStore encryptionStore;

    @Override
    public AuthenticationTokenValidator get() {
      try {
        return build(httpStrategy, configuration, encryptionStore);
      } catch (OpsException e) {
        throw new IllegalStateException("Error building AuthenticationTokenValidator", e);
      }
    }

  }

}
TOP

Related Classes of org.platformlayer.auth.system.PlatformLayerAuthAdminClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.