forked from minio/minio-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add AssumeRoleWithCertificate credential provider. (minio#1239)
Signed-off-by: Bala.FA <[email protected]>
- Loading branch information
1 parent
ca1e8b0
commit 898f9c3
Showing
3 changed files
with
234 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
api/src/main/java/io/minio/credentials/CertificateIdentityProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2021 MinIO, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.minio.credentials; | ||
|
||
import java.io.IOException; | ||
import java.security.GeneralSecurityException; | ||
import java.util.Objects; | ||
import javax.annotation.Nonnull; | ||
import javax.annotation.Nullable; | ||
import javax.net.ssl.SSLSocketFactory; | ||
import javax.net.ssl.X509TrustManager; | ||
import okhttp3.HttpUrl; | ||
import okhttp3.MediaType; | ||
import okhttp3.OkHttpClient; | ||
import okhttp3.Request; | ||
import okhttp3.RequestBody; | ||
import org.simpleframework.xml.Element; | ||
import org.simpleframework.xml.Namespace; | ||
import org.simpleframework.xml.Path; | ||
import org.simpleframework.xml.Root; | ||
|
||
/** | ||
* Credential provider using <a | ||
* href="https://github.com/minio/minio/blob/master/docs/sts/tls.md">AssumeRoleWithCertificate | ||
* API</a>. | ||
*/ | ||
public class CertificateIdentityProvider extends AssumeRoleBaseProvider { | ||
private static final RequestBody EMPTY_BODY = | ||
RequestBody.create(new byte[] {}, MediaType.parse("application/octet-stream")); | ||
private final Request request; | ||
|
||
public CertificateIdentityProvider( | ||
@Nonnull String stsEndpoint, | ||
@Nullable SSLSocketFactory sslSocketFactory, | ||
@Nullable X509TrustManager trustManager, | ||
@Nullable Integer durationSeconds, | ||
@Nullable OkHttpClient customHttpClient) | ||
throws GeneralSecurityException, IOException { | ||
super(customHttpClient, sslSocketFactory, trustManager); | ||
stsEndpoint = Objects.requireNonNull(stsEndpoint, "STS endpoint cannot be empty"); | ||
HttpUrl url = Objects.requireNonNull(HttpUrl.parse(stsEndpoint), "Invalid STS endpoint"); | ||
if (!url.isHttps()) { | ||
throw new IllegalArgumentException("STS endpoint scheme must be HTTPS"); | ||
} | ||
|
||
HttpUrl.Builder urlBuilder = | ||
newUrlBuilder( | ||
url, | ||
"AssumeRoleWithCertificate", | ||
getValidDurationSeconds(durationSeconds), | ||
null, | ||
null, | ||
null); | ||
url = urlBuilder.build(); | ||
this.request = new Request.Builder().url(url).method("POST", EMPTY_BODY).build(); | ||
} | ||
|
||
@Override | ||
protected Request getRequest() { | ||
return this.request; | ||
} | ||
|
||
@Override | ||
protected Class<? extends AssumeRoleBaseProvider.Response> getResponseClass() { | ||
return CertificateIdentityResponse.class; | ||
} | ||
|
||
/** Object representation of response XML of AssumeRoleWithCertificate API. */ | ||
@Root(name = "AssumeRoleWithCertificateResponse", strict = false) | ||
@Namespace(reference = "https://sts.amazonaws.com/doc/2011-06-15/") | ||
public static class CertificateIdentityResponse implements AssumeRoleBaseProvider.Response { | ||
@Path(value = "AssumeRoleWithCertificateResult") | ||
@Element(name = "Credentials") | ||
private Credentials credentials; | ||
|
||
public Credentials getCredentials() { | ||
return credentials; | ||
} | ||
} | ||
} |
108 changes: 108 additions & 0 deletions
108
examples/MinioClientWithCertificateIdentityProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2021 MinIO, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import io.minio.MinioClient; | ||
import io.minio.StatObjectArgs; | ||
import io.minio.StatObjectResponse; | ||
import io.minio.credentials.CertificateIdentityProvider; | ||
import io.minio.credentials.Provider; | ||
import javax.net.ssl.SSLSocketFactory; | ||
import javax.net.ssl.X509TrustManager; | ||
|
||
public class MinioClientWithCertificateIdentityProvider { | ||
public static void main(String[] args) throws Exception { | ||
// STS endpoint usually point to MinIO server. | ||
String stsEndpoint = "https://STS-HOST:STS-PORT/"; | ||
|
||
// SSL socket factory. | ||
SSLSocketFactory sslSocketFactory = null; | ||
|
||
// Trust manager. | ||
X509TrustManager trustManager = null; | ||
|
||
// Below is a sample code to construct sslSocketFactory and trustManager for self-signed | ||
// certificates (server and client) used in a MinIO server setup. | ||
// | ||
// CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); | ||
// | ||
// Certificate serverCertificate = null; | ||
// try (FileInputStream fis = new FileInputStream("/home/bala/.minio/certs/public.crt")) { | ||
// serverCertificate = certificateFactory.generateCertificate(fis); | ||
// } | ||
// | ||
// KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); | ||
// trustStore.load(null, "secret".toCharArray()); | ||
// | ||
// trustStore.setCertificateEntry("server-certificate", serverCertificate); | ||
// | ||
// String privateKeyString = | ||
// new String( | ||
// Files.readAllBytes(Paths.get("/home/bala/.minio/certs/CAs/client1.key")), | ||
// Charset.defaultCharset()) | ||
// .replace("-----BEGIN PRIVATE KEY-----", "") | ||
// .replaceAll(System.lineSeparator(), "") | ||
// .replace("-----END PRIVATE KEY-----", ""); | ||
// | ||
// byte[] privateKey = Base64.getDecoder().decode(privateKeyString); | ||
// KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | ||
// PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); | ||
// | ||
// Certificate certificateChain = null; | ||
// try (FileInputStream fis = new FileInputStream("/home/bala/.minio/certs/CAs/client1.crt")) { | ||
// certificateChain = certificateFactory.generateCertificate(fis); | ||
// } | ||
// | ||
// KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType()); | ||
// identityStore.load(null, "secret".toCharArray()); | ||
// identityStore.setKeyEntry( | ||
// "client", | ||
// keyFactory.generatePrivate(keySpec), | ||
// "secret".toCharArray(), | ||
// new Certificate[] {certificateChain}); | ||
// | ||
// TrustManagerFactory trustManagerFactory = | ||
// TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); | ||
// trustManagerFactory.init(trustStore); | ||
// TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); | ||
// | ||
// KeyManagerFactory keyManagerFactory = | ||
// KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); | ||
// keyManagerFactory.init(identityStore, "secret".toCharArray()); | ||
// KeyManager[] keyManagers = keyManagerFactory.getKeyManagers(); | ||
// | ||
// SSLContext sslContext = SSLContext.getInstance("TLS"); | ||
// sslContext.init(keyManagers, trustManagers, null); | ||
// | ||
// SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); | ||
// X509TrustManager trustManager = (X509TrustManager) trustManagers[0]; | ||
// | ||
|
||
Provider provider = | ||
new CertificateIdentityProvider(stsEndpoint, sslSocketFactory, trustManager, null, null); | ||
|
||
MinioClient minioClient = | ||
MinioClient.builder() | ||
.endpoint("https://MINIO-HOST:MINIO-PORT") | ||
.credentialsProvider(provider) | ||
.build(); | ||
|
||
// Get information of an object. | ||
StatObjectResponse stat = | ||
minioClient.statObject( | ||
StatObjectArgs.builder().bucket("my-bucketname").object("my-objectname").build()); | ||
System.out.println(stat); | ||
} | ||
} |