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

com.clouway.oauth2.IssueNewTokenActivity Maven / Gradle / Ivy

package com.clouway.oauth2;

import com.clouway.friendlyserve.Request;
import com.clouway.friendlyserve.Response;
import com.clouway.oauth2.client.Client;
import com.clouway.oauth2.client.ClientKeyStore;
import com.clouway.oauth2.jws.Pem;
import com.clouway.oauth2.jws.Pem.Block;
import com.clouway.oauth2.token.BearerToken;
import com.clouway.oauth2.token.GrantType;
import com.clouway.oauth2.token.TokenResponse;
import com.clouway.oauth2.token.Tokens;
import com.google.gson.JsonObject;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;


/**
 * IssueNewTokenActivity is representing the activity which is performed for issuing of new token.
 *
 * @author Miroslav Genov ([email protected])
 */
class IssueNewTokenActivity implements AuthorizedClientActivity {
  private final Tokens tokens;
  private final ClientKeyStore keyStore;

  IssueNewTokenActivity(Tokens tokens, ClientKeyStore keyStore) {
    this.tokens = tokens;
    this.keyStore = keyStore;
  }

  @Override
  public Response execute(Client client, Identity identity, Set scopes, Request request, DateTime instant) {
    TokenResponse response = tokens.issueToken(GrantType.AUTHORIZATION_CODE, client, identity, scopes, instant);
    if (!response.isSuccessful()) {
      return OAuthError.invalidRequest("Token cannot be issued.");
    }

    BearerToken accessToken = response.accessToken;
    Map certificates = keyStore.privateCertificates();
    String idToken = "";

    if (certificates != null && !certificates.isEmpty()) {
      String certKey = randomKey(certificates);
      Pem.Block key = certificates.get(certKey);
      String host = request.header("Host");

      idToken = Jwts.builder()
              .setHeaderParam("cid", certKey)//CertificateId - the ID of the certificate that the token was signed with.
              .setIssuer(host)
              .setAudience(client.id)
              .setSubject(identity.id())
              .setIssuedAt(instant.asDate())
              .setExpiration(new Date(accessToken.expirationTimestamp()))
              .claim("identity", identityAsJson(identity).toString())
              .signWith(SignatureAlgorithm.RS256, parsePem(key))
              .compact();
    }
    return new BearerTokenResponse(accessToken.value, accessToken.ttlSeconds(instant), response.refreshToken, idToken);
  }

  private String randomKey(Map map) {
    Random random = new Random();
    List certId = new ArrayList<>(map.keySet());
    return certId.get(random.nextInt(certId.size()));
  }

  private PrivateKey parsePem(Pem.Block privateKey) {
    try {
      PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey.getBytes());
      KeyFactory kf = KeyFactory.getInstance("RSA");
      return kf.generatePrivate(keySpec);
    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
      e.printStackTrace();
    }
    return null;
  }

  private JsonObject identityAsJson(Identity identity) {
    JsonObject o = new JsonObject();

    o.addProperty("id", identity.id());
    o.addProperty("name", identity.name());
    o.addProperty("email", identity.email());
    o.addProperty("given_name", identity.givenName());
    o.addProperty("family_name", identity.familyName());

    Map claims = identity.claims();

    for (String key : claims.keySet()) {
      Object value = claims.get(key);

      if (value instanceof String) {
        o.addProperty(key, (String) value);
      }
      if (value instanceof Number) {
        o.addProperty(key, (Number) value);
      }

      if (value instanceof Boolean) {
        o.addProperty(key, (Boolean) value);
      }
    }
    return o;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy