In the distributed storage software we use, clients authenticate with client certificates over TLS HTTP with the head nodes, which may either proxy the data to the storage pools or redirect the client to issue its PUT to the storage pools over unauthenticated HTTP.
The mechanism of redirect-on-PUT requires that the client _must_ issue a "expect 100 continue" on its initial request. This is so that the server will have the ability to decide on if to accept the data directly (by responding with a 100 continue), or redirect/reject/whatever with 30x/40x.
Our storage uses dynamically opened ports on the storage nodes and have a GUID as query parameter to figure out where to put stuff, but it's in no way secure. In your case, you'd either have to delegate credentials to the clients as part of the URLs, or make your S3 world-writable and pray.