I am trying to run the S3App.java (RESTful Web Services publisher O'Reilly) and
getting a HTTP response code of 403 Forbidden. S3App.java extends
S3Authorized.java which defines the following keys (constants),
public final static String PUBLIC_KEY = "0F9DBXKB5274JKTJ8DG2";
public final static String PRIVATE_KEY =
"GuUHQ086WawbwvVl3JPl9JIk4VOtLcllkvIb0b7w";
which are not allowing me to authenticate properly. I have compiled, S3App,
S3Authorized, S3Bucket, and S3Object, successfully.
Please might someone shed some light on what I am doing wrong?
I tried the following work around. I created an account at AWS. When doing so,
I was assigned an "Access Key ID" and a "Secret Access Key". I updated the
code's original PUBLIC_KEY value by replacing it with the value of my
AWS_Access_Key_ID and PRIVATE_KEY with my AWS_Secret_Access_Key value. The work
around failed. I figured this was a long shot and would probably fail; because
I was assuming the AWS_Secret_Access_Key is suppose to be used to create
signatures for requests made to retrieve S3 content. However, I could have
misunderstood the intent of an AWS_Secret_Access_Key and how to use it properly.
I have attached all the java code.
Cheers and thanks for reading,
woodHack
/*
* Copyright 2005-2007 Noelios Consulting.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License (the "License"). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.txt See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each file and
* include the License file at http://www.opensource.org/licenses/cddl1.txt If
* applicable, add the following below this CDDL HEADER, with the fields
* enclosed by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*/
package org.restlet.example.book.rest.ch3;
import java.util.ArrayList;
import java.util.List;
import org.restlet.data.Response;
import org.restlet.resource.DomRepresentation;
import org.w3c.dom.Node;
/**
* Amazon S3 client application. Returns a list of buckets.
*
* @author Jerome Louvel (cont...@noelios.com)
*/
public class S3App extends S3Authorized {
public static void main(String... args) {
for (S3Bucket bucket : new S3App().getBuckets()) {
System.out.println(bucket.getName() + " : " + bucket.getUri());
}
}
public List<S3Bucket> getBuckets() {
List<S3Bucket> result = new ArrayList<S3Bucket>();
// Fetch a resource: an XML document with our list of buckets
Response response = authorizedGet(HOST);
DomRepresentation document = response.getEntityAsDom();
// Use XPath to find the bucket names
for (Node node : document.getNodes("//Bucket/Name")) {
result.add(new S3Bucket(node.getTextContent()));
}
return result;
}
}
/*
* Copyright 2005-2007 Noelios Consulting.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License (the "License"). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.txt See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each file and
* include the License file at http://www.opensource.org/licenses/cddl1.txt If
* applicable, add the following below this CDDL HEADER, with the fields
* enclosed by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*/
package org.restlet.example.book.rest.ch3;
import org.restlet.Client;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.resource.Representation;
/**
* Amazon S3 client. Support class handling authorized requests.
*
* @author Jerome Louvel (cont...@noelios.com)
*/
public class S3Authorized {
public final static String PUBLIC_KEY = "0F9DBXKB5274JKTJ8DG2";
public final static String PRIVATE_KEY =
"GuUHQ086WawbwvVl3JPl9JIk4VOtLcllkvIb0b7w";
public final static String HOST = "https://s3.amazonaws.com/";
private static Response handleAuthorized(Method method, String uri,
Representation entity) {
// Send an authenticated request
Request request = new Request(method, HOST, entity);
request.setChallengeResponse(new ChallengeResponse(
ChallengeScheme.HTTP_AWS, PUBLIC_KEY, PRIVATE_KEY));
return new Client(Protocol.HTTPS).handle(request);
}
public static Response authorizedHead(String uri) {
return handleAuthorized(Method.HEAD, uri, null);
}
public static Response authorizedGet(String uri) {
return handleAuthorized(Method.GET, uri, null);
}
public static Response authorizedPut(String uri, Representation entity) {
return handleAuthorized(Method.PUT, uri, entity);
}
public static Response authorizedDelete(String uri) {
return handleAuthorized(Method.DELETE, uri, null);
}
}
/*
* Copyright 2005-2007 Noelios Consulting.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License (the "License"). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.txt See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each file and
* include the License file at http://www.opensource.org/licenses/cddl1.txt If
* applicable, add the following below this CDDL HEADER, with the fields
* enclosed by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*/
package org.restlet.example.book.rest.ch3;
import java.util.ArrayList;
import java.util.List;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.DomRepresentation;
import org.w3c.dom.Node;
/**
* Amazon S3 bucket.
*
* @author Jerome Louvel (cont...@noelios.com)
*/
public class S3Bucket extends S3Authorized {
private String name;
private boolean truncated;
public S3Bucket(String name) {
this.name = name;
}
/**
* Stores this bucket on S3. Analagous to ActiveRecord::Base#save, which
* stores an object in the database.
*/
public Status save() {
return authorizedPut(getUri(), null).getStatus();
}
/**
* Deletes this bucket.
*/
public Status delete() {
return authorizedDelete(getUri()).getStatus();
}
/**
* Get the objects in this bucket: all of them, or some subset.
*
* If S3 decides not to return the whole bucket/subset, the second return
* value will be set to true. To get the rest of the objects, you'll need to
* manipulate the subset options.
*
* Subset options are :Prefix, :Marker, :Delimiter, :MaxKeys. For details,
* see the S3 docs on "Listing Keys".
*
* @return The objects in this nucket.
*/
public List<S3Object> getObjects(String prefix, String marker,
String delimiter, Integer maxKeys) {
List<S3Object> result = new ArrayList<S3Object>();
// Construct the request URI by appending optional listing keys
StringBuilder uri = new StringBuilder().append(getUri());
String suffix = "?";
if (prefix != null) {
uri.append(suffix).append("prefix=").append(prefix);
suffix = "&";
}
if (marker != null) {
uri.append(suffix).append("marker=").append(marker);
suffix = "&";
}
if (delimiter != null) {
uri.append(suffix).append("delimiter=").append(delimiter);
suffix = "&";
}
if (maxKeys != null) {
uri.append(suffix).append("maxKeys=").append(maxKeys);
suffix = "&";
}
// Make the request and parse the document.
Response response = authorizedGet(uri.toString());
DomRepresentation document = response.getEntityAsDom();
// Update the truncated flag
this.truncated = document.getNodes("//IsTruncated").get(0)
.getTextContent().equals("true");
// Browse the list of object keys
for (Node node : document.getNodes("//Contents/Key")) {
result.add(new S3Object(this, node.getTextContent()));
}
return result;
}
public boolean isTruncated() {
return this.truncated;
}
public String getUri() {
return S3App.HOST + getName();
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
/*
* Copyright 2005-2007 Noelios Consulting.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License (the "License"). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.txt See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each file and
* include the License file at http://www.opensource.org/licenses/cddl1.txt If
* applicable, add the following below this CDDL HEADER, with the fields
* enclosed by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*/
package org.restlet.example.book.rest.ch3;
import org.restlet.data.Reference;
import org.restlet.data.Status;
import org.restlet.resource.Representation;
import org.restlet.resource.Variant;
/**
* Amazon S3 object.
*
* @author Jerome Louvel (cont...@noelios.com)
*/
public class S3Object extends S3Authorized {
private S3Bucket bucket;
private Variant metadata;
private String name;
public S3Object(S3Bucket bucket, String name) {
this.bucket = bucket;
this.name = name;
}
/**
* Retrieves the metadata hash for this object, possibly fetchingit from S3.
*
* @return The metadata hash for this object, possibly fetchingit from S3.
*/
public Variant getMetadata() {
if (this.metadata == null)
this.metadata = authorizedHead(getUri()).getEntity();
return this.metadata;
}
/**
* Retrieves the value of this object, always fetching it (along with the
* metadata) from S3.
*
* @return The value of this object.
*/
public Representation getValue() {
return authorizedGet(getUri()).getEntity();
}
/**
* Store this object on S3 with a given value.
*
* @param value
* The value of the object to store.
*/
public Status save(Representation value) {
this.metadata = value;
return authorizedPut(getUri(), value).getStatus();
}
/**
* Deletes this bucket.
*/
public Status delete() {
return authorizedDelete(getUri()).getStatus();
}
public String getUri() {
return getBucket().getUri() + "/" + Reference.encode(getName());
}
public S3Bucket getBucket() {
return this.bucket;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}