Step 5: Create a certificate in the destination environment
POST {{apiPath}}/environments/{{destinationEnvID}}/certificates
Create a certificate in the destination environment using a POST {{apiPath}}/environments/{{destinationEnvID}}/certificates request. Copy and save the certificate ID. You’ll use it when creating the IdP.
-
The
usageTypevalue must be set to "SIGNING". -
The
fileentry must reference the PEM or PKCS7 file containing the source environment key you downloaded in the initial step. Creating the certificate using the PEM or PKCS7 file transfers the key from the source environment to the destination environment.
|
If the certificate used by the IdP in the destination environment doesn’t match the key used by the source environment application, the authentication flow fails. |
Example Request
-
cURL
-
C#
-
Go
-
HTTP
-
Java
-
jQuery
-
NodeJS
-
Python
-
PHP
-
Ruby
-
Swift
curl --location --globoff '{{apiPath}}/environments/{{destinationEnvID}}/certificates' \
--header 'Authorization: Bearer {{accessToken}}' \
--form 'usageType="SIGNING"' \
--form 'file=@"/path/to/file"'
var options = new RestClientOptions("{{apiPath}}/environments/{{destinationEnvID}}/certificates")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Post);
request.AddHeader("Authorization", "Bearer {{accessToken}}");
request.AlwaysMultipartFormData = true;
request.AddParameter("usageType", "SIGNING");
request.AddFile("file", "/path/to/file");
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
package main
import (
"fmt"
"bytes"
"mime/multipart"
"os"
"path/filepath"
"net/http"
"io"
)
func main() {
url := "{{apiPath}}/environments/{{destinationEnvID}}/certificates"
method := "POST"
payload := &bytes.Buffer{}
writer := multipart.NewWriter(payload)
_ = writer.WriteField("usageType", "SIGNING")
file, errFile2 := os.Open("/path/to/file")
defer file.Close()
part2,
errFile2 := writer.CreateFormFile("file",filepath.Base("/path/to/file"))
_, errFile2 = io.Copy(part2, file)
if errFile2 != nil {
fmt.Println(errFile2)
return
}
err := writer.Close()
if err != nil {
fmt.Println(err)
return
}
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Authorization", "Bearer {{accessToken}}")
req.Header.Set("Content-Type", writer.FormDataContentType())
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
POST /environments/{{destinationEnvID}}/certificates HTTP/1.1
Host: {{apiPath}}
Authorization: Bearer {{accessToken}}
Content-Length: 289
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="usageType"
SIGNING
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="file"
Content-Type: <Content-Type header here>
(data)
------WebKitFormBoundary7MA4YWxkTrZu0gW--
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("usageType","SIGNING")
.addFormDataPart("file","file",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("/path/to/file")))
.build();
Request request = new Request.Builder()
.url("{{apiPath}}/environments/{{destinationEnvID}}/certificates")
.method("POST", body)
.addHeader("Authorization", "Bearer {{accessToken}}")
.addHeader("Content-Length", "")
.build();
Response response = client.newCall(request).execute();
var form = new FormData();
form.append("usageType", "SIGNING");
form.append("file", fileInput.files[0], "file");
var settings = {
"url": "{{apiPath}}/environments/{{destinationEnvID}}/certificates",
"method": "POST",
"timeout": 0,
"headers": {
"Authorization": "Bearer {{accessToken}}",
"Content-Length": ""
},
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
$.ajax(settings).done(function (response) {
console.log(response);
});
var request = require('request');
var fs = require('fs');
var options = {
'method': 'POST',
'url': '{{apiPath}}/environments/{{destinationEnvID}}/certificates',
'headers': {
'Authorization': 'Bearer {{accessToken}}',
'Content-Length': ''
},
formData: {
'usageType': 'SIGNING',
'file': {
'value': fs.createReadStream('/path/to/file'),
'options': {
'filename': 'file',
'contentType': null
}
}
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
url = "{{apiPath}}/environments/{{destinationEnvID}}/certificates"
payload = {'usageType': 'SIGNING'}
files=[
('file',('file',open('/path/to/file','rb'),'application/octet-stream'))
]
headers = {
'Authorization': 'Bearer {{accessToken}}',
'Content-Length': ''
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('{{apiPath}}/environments/{{destinationEnvID}}/certificates');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
'follow_redirects' => TRUE
));
$request->setHeader(array(
'Authorization' => 'Bearer {{accessToken}}',
'Content-Length' => ''
));
$request->addPostParameter(array(
'usageType' => 'SIGNING'
));
$request->addUpload('file', '/path/to/file', 'file', '<Content-Type Header>');
try {
$response = $request->send();
if ($response->getStatus() == 200) {
echo $response->getBody();
}
else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
}
catch(HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
require "uri"
require "net/http"
url = URI("{{apiPath}}/environments/{{destinationEnvID}}/certificates")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Bearer {{accessToken}}"
request["Content-Length"] = ""
form_data = [['usageType', 'SIGNING'],['file', File.open('/path/to/file')]]
request.set_form form_data, 'multipart/form-data'
response = http.request(request)
puts response.read_body
let parameters = [
[
"key": "usageType",
"value": "SIGNING",
"type": "text"
],
[
"key": "file",
"src": "/path/to/file",
"type": "file"
]] as [[String: Any]]
let boundary = "Boundary-\(UUID().uuidString)"
var body = Data()
var error: Error? = nil
for param in parameters {
if param["disabled"] != nil { continue }
let paramName = param["key"]!
body += Data("--\(boundary)\r\n".utf8)
body += Data("Content-Disposition:form-data; name=\"\(paramName)\"".utf8)
if param["contentType"] != nil {
body += Data("\r\nContent-Type: \(param["contentType"] as! String)".utf8)
}
let paramType = param["type"] as! String
if paramType == "text" {
let paramValue = param["value"] as! String
body += Data("\r\n\r\n\(paramValue)\r\n".utf8)
} else {
let paramSrc = param["src"] as! String
let fileURL = URL(fileURLWithPath: paramSrc)
if let fileContent = try? Data(contentsOf: fileURL) {
body += Data("; filename=\"\(paramSrc)\"\r\n".utf8)
body += Data("Content-Type: \"content-type header\"\r\n".utf8)
body += Data("\r\n".utf8)
body += fileContent
body += Data("\r\n".utf8)
}
}
}
body += Data("--\(boundary)--\r\n".utf8);
let postData = body
var request = URLRequest(url: URL(string: "{{apiPath}}/environments/{{destinationEnvID}}/certificates")!,timeoutInterval: Double.infinity)
request.addValue("Bearer {{accessToken}}", forHTTPHeaderField: "Authorization")
request.addValue("", forHTTPHeaderField: "Content-Length")
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
}
task.resume()
Example Response
202 Accepted
{
"_links": {
"self": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/certificates"
}
},
"id": "409e8711-7d1b-4035-afc6-561c2b86286b",
"name": "kb doc test",
"serialNumber": 1604411669268,
"issuerDN": "CN=kb doc test,OU=,O=myOrg,L=,ST=,C=CA",
"subjectDN": "CN=kb doc test,OU=,O=myOrg,L=,ST=,C=CA",
"algorithm": "RSA",
"keyLength": 2048,
"createdAt": "2020-11-24T15:39:55.325Z",
"expiresAt": "2021-11-03T13:54:29.000Z",
"startsAt": "2020-11-03T13:54:29.000Z",
"validityPeriod": 365,
"signatureAlgorithm": "SHA256withRSA",
"usageType": "SIGNING",
"status": "VALID",
"environment": {
"id": "abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
}
}