Java tutorial
/* * Copyright 2014 Steve Jones. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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 com.github.sjones4.youcan.youtoken; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.AmazonWebServiceRequest; import com.amazonaws.ClientConfiguration; import com.amazonaws.Request; import com.amazonaws.Response; import com.amazonaws.SignableRequest; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import com.amazonaws.auth.Signer; import com.amazonaws.http.DefaultErrorResponseHandler; import com.amazonaws.http.ExecutionContext; import com.amazonaws.http.StaxResponseHandler; import com.amazonaws.internal.StaticCredentialsProvider; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient; import com.amazonaws.transform.StaxUnmarshallerContext; import com.amazonaws.transform.Unmarshaller; import com.amazonaws.util.AWSRequestMetrics; import com.amazonaws.util.BinaryUtils; import com.amazonaws.util.CredentialUtils; import com.github.sjones4.youcan.youtoken.model.GetAccessTokenRequest; import com.github.sjones4.youcan.youtoken.model.GetAccessTokenResult; import com.github.sjones4.youcan.youtoken.model.GetImpersonationTokenRequest; import com.github.sjones4.youcan.youtoken.model.GetImpersonationTokenResult; import com.github.sjones4.youcan.youtoken.model.transform.GetAccessTokenRequestMarshaller; import com.github.sjones4.youcan.youtoken.model.transform.GetAccessTokenResultStaxUnmarshaller; import com.github.sjones4.youcan.youtoken.model.transform.GetImpersonationTokenRequestMarshaller; import com.github.sjones4.youcan.youtoken.model.transform.GetImpersonationTokenResultStaxUnmarshaller; /** * */ public class YouTokenClient extends AWSSecurityTokenServiceClient implements YouToken { private final AWSCredentialsProvider awsCredentialsProvider; public YouTokenClient(final AWSCredentialsProvider awsCredentialsProvider, final ClientConfiguration clientConfiguration) { super(awsCredentialsProvider, clientConfiguration); this.awsCredentialsProvider = awsCredentialsProvider; } public YouTokenClient() { this(new DefaultAWSCredentialsProviderChain(), new ClientConfiguration()); } public YouTokenClient(final AWSCredentials awsCredentials) { this(new StaticCredentialsProvider(awsCredentials), new ClientConfiguration()); } public YouTokenClient(final AWSCredentials awsCredentials, final ClientConfiguration clientConfiguration) { this(new StaticCredentialsProvider(awsCredentials), clientConfiguration); } public YouTokenClient(final ClientConfiguration clientConfiguration) { this(new DefaultAWSCredentialsProviderChain(), clientConfiguration); } public YouTokenClient(final AWSCredentialsProvider awsCredentialsProvider) { this(awsCredentialsProvider, new ClientConfiguration()); } @Override public GetAccessTokenResult getAccessToken() throws AmazonServiceException, AmazonClientException { return getAccessToken(new GetAccessTokenRequest()); } @Override public GetAccessTokenResult getAccessToken(final GetAccessTokenRequest getAccessTokenRequest) throws AmazonServiceException, AmazonClientException { ExecutionContext executionContext = createExecutionContext(getAccessTokenRequest); AWSRequestMetrics awsRequestMetrics = executionContext.getAwsRequestMetrics(); Request<GetAccessTokenRequest> request = null; Response<GetAccessTokenResult> response = null; awsRequestMetrics.startEvent(AWSRequestMetrics.Field.ClientExecuteTime); try { request = new GetAccessTokenRequestMarshaller().marshall(getAccessTokenRequest); // Binds the request metrics to the current request. request.setAWSRequestMetrics(awsRequestMetrics); response = invoke(request, new GetAccessTokenResultStaxUnmarshaller(), executionContext); return response.getAwsResponse(); } finally { endClientExecution(awsRequestMetrics, request, response); } } @Override public GetImpersonationTokenResult getImpersonationToken( final GetImpersonationTokenRequest getImpersonationTokenRequest) throws AmazonServiceException, AmazonClientException { ExecutionContext executionContext = createExecutionContext(getImpersonationTokenRequest); AWSRequestMetrics awsRequestMetrics = executionContext.getAwsRequestMetrics(); Request<GetImpersonationTokenRequest> request = null; Response<GetImpersonationTokenResult> response = null; awsRequestMetrics.startEvent(AWSRequestMetrics.Field.ClientExecuteTime); try { request = new GetImpersonationTokenRequestMarshaller().marshall(getImpersonationTokenRequest); // Binds the request metrics to the current request. request.setAWSRequestMetrics(awsRequestMetrics); response = invoke(request, new GetImpersonationTokenResultStaxUnmarshaller(), executionContext); return response.getAwsResponse(); } finally { endClientExecution(awsRequestMetrics, request, response); } } protected ExecutionContext createExecutionContext(final AmazonWebServiceRequest req) { boolean isMetricsEnabled = isRequestMetricsEnabled(req) || isProfilingEnabled(); return new ExecutionContext(requestHandler2s, isMetricsEnabled, this) { @Override public Signer getSignerByURI(final URI uri) { if (getCredentialsProvider().getCredentials() instanceof PasswordCredentials) { return new PasswordSigner(); } return super.getSignerByURI(uri); } }; } private <X, Y extends AmazonWebServiceRequest> Response<X> invoke(final Request<Y> request, final Unmarshaller<X, StaxUnmarshallerContext> unmarshaller, final ExecutionContext executionContext) { request.setEndpoint(endpoint); request.setTimeOffset(timeOffset); executionContext.setCredentialsProvider( CredentialUtils.getCredentialsProvider(request.getOriginalRequest(), awsCredentialsProvider)); StaxResponseHandler<X> responseHandler = new StaxResponseHandler<X>(unmarshaller); DefaultErrorResponseHandler errorResponseHandler = new DefaultErrorResponseHandler(exceptionUnmarshallers); return client.execute(request, responseHandler, errorResponseHandler, executionContext); } private static final class PasswordSigner implements Signer { protected static final String PREFIX = "Basic "; @Override public void sign(final SignableRequest<?> request, final AWSCredentials credentials) { if (credentials instanceof PasswordCredentials) { final PasswordCredentials passwordCredentials = (PasswordCredentials) credentials; final Charset utf8 = StandardCharsets.UTF_8; final ByteArrayOutputStream headerPassword = new ByteArrayOutputStream(); final OutputStreamWriter headerWriter = new OutputStreamWriter(headerPassword, utf8); try { headerWriter.append(BinaryUtils.toBase64(passwordCredentials.getUserName().getBytes(utf8))); headerWriter.append('@'); headerWriter.append(BinaryUtils.toBase64(passwordCredentials.getAccountName().getBytes(utf8))); if (credentials instanceof PasswordUpdateCredentials) { final PasswordUpdateCredentials passwordUpdateCredentials = (PasswordUpdateCredentials) credentials; headerWriter.append(';'); headerWriter.append( BinaryUtils.toBase64(new String(passwordCredentials.getPassword()).getBytes(utf8))); headerWriter.append('@'); for (int i = 0; i < passwordUpdateCredentials.getPasswordUpdate().length; i++) { headerWriter.append(passwordUpdateCredentials.getPasswordUpdate()[i]); } } else { headerWriter.append(':'); for (int i = 0; i < passwordCredentials.getPassword().length; i++) { headerWriter.append(passwordCredentials.getPassword()[i]); } } headerWriter.flush(); headerWriter.close(); } catch (IOException e) { throw new AmazonClientException("Unable to construct header for password credentials", e); } final String authorizationHeader = PREFIX + BinaryUtils.toBase64(headerPassword.toByteArray()); request.addHeader("Authorization", authorizationHeader); } } } }