Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import java.util.regex.Pattern;

import org.apache.hadoop.ozone.s3.exception.OS3Exception;
import org.apache.hadoop.ozone.s3.header.AuthorizationHeaderV2;
import org.apache.hadoop.ozone.s3.header.AuthorizationHeaderV4;
import org.apache.hadoop.ozone.s3.header.Credential;

Expand All @@ -54,15 +55,15 @@
import org.slf4j.LoggerFactory;

/**
* Parser to process AWS v4 auth request. Creates string to sign and auth
* Parser to process AWS V2 & V4 auth request. Creates string to sign and auth
* header. For more details refer to AWS documentation https://docs.aws
* .amazon.com/general/latest/gr/sigv4-create-canonical-request.html.
**/
@RequestScoped
public class AWSV4SignatureProcessor implements SignatureProcessor {
public class AWSSignatureProcessor implements SignatureProcessor {

private final static Logger LOG =
LoggerFactory.getLogger(AWSV4SignatureProcessor.class);
LoggerFactory.getLogger(AWSSignatureProcessor.class);

@Context
private ContainerRequestContext context;
Expand All @@ -72,13 +73,12 @@ public class AWSV4SignatureProcessor implements SignatureProcessor {
private String uri;
private String method;
private AuthorizationHeaderV4 v4Header;
private AuthorizationHeaderV2 v2Header;
private String stringToSign;

@PostConstruct
public void init()
throws Exception {
LOG.info("Initializing request header parser");

//header map is MUTABLE. It's better to save it here. (with lower case
// keys!!!)
this.headers = new LowerCaseKeyStringMap(new HashMap<>());
Expand Down Expand Up @@ -107,10 +107,18 @@ public void init()
this.uri = context.getUriInfo().getRequestUri().getPath();

this.method = context.getMethod();
if (v4Header == null) {
v4Header = new AuthorizationHeaderV4(headers.get(AUTHORIZATION_HEADER));
String authHeader = headers.get(AUTHORIZATION_HEADER);
String[] split = authHeader.split(" ");
if (split[0].equals(AuthorizationHeaderV2.IDENTIFIER)) {
if (v2Header == null) {
v2Header = new AuthorizationHeaderV2(authHeader);
}
} else {
if (v4Header == null) {
v4Header = new AuthorizationHeaderV4(authHeader);
}
parse();
}
parse();
}


Expand Down Expand Up @@ -320,11 +328,13 @@ public static String hash(String payload) throws NoSuchAlgorithmException {
}

public String getAwsAccessId() {
return v4Header.getAccessKeyID();
return (v4Header != null ? v4Header.getAccessKeyID() :
v2Header != null ? v2Header.getAccessKeyID() : "");
}

public String getSignature() {
return v4Header.getSignature();
return (v4Header != null ? v4Header.getSignature() :
v2Header != null ? v2Header.getSignature() : "");
}

public String getStringToSign() throws Exception {
Expand All @@ -342,6 +352,11 @@ public void setV4Header(
this.v4Header = v4Header;
}

@VisibleForTesting
public void setV2Header(AuthorizationHeaderV2 v2Header) {
this.v2Header = v2Header;
}

/**
* A simple map which forces lower case key usage.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class OzoneClientProducer {
private OzoneClient client;

@Inject
private SignatureProcessor v4RequestParser;
private SignatureProcessor signatureParser;

@Inject
private OzoneConfiguration ozoneConfiguration;
Expand All @@ -76,7 +76,7 @@ public void destory() throws IOException {

private OzoneClient getClient(OzoneConfiguration config) throws IOException {
try {
String awsAccessId = v4RequestParser.getAwsAccessId();
String awsAccessId = signatureParser.getAwsAccessId();
UserGroupInformation remoteUser =
UserGroupInformation.createRemoteUser(awsAccessId);
if (OzoneSecurityUtil.isSecurityEnabled(config)) {
Expand All @@ -85,8 +85,8 @@ private OzoneClient getClient(OzoneConfiguration config) throws IOException {

OzoneTokenIdentifier identifier = new OzoneTokenIdentifier();
identifier.setTokenType(S3AUTHINFO);
identifier.setStrToSign(v4RequestParser.getStringToSign());
identifier.setSignature(v4RequestParser.getSignature());
identifier.setStrToSign(signatureParser.getStringToSign());
identifier.setSignature(signatureParser.getSignature());
identifier.setAwsAccessId(awsAccessId);
identifier.setOwner(new Text(awsAccessId));
if (LOG.isTraceEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
*/
public class AuthorizationHeaderV2 {

private final static String IDENTIFIER = "AWS";
public final static String IDENTIFIER = "AWS";
private String authHeader;
private String identifier;
private String accessKeyID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.MALFORMED_HEADER;
import static org.apache.hadoop.ozone.s3.AWSV4SignatureProcessor.AWS4_SIGNING_ALGORITHM;
import static org.apache.hadoop.ozone.s3.AWSV4SignatureProcessor.DATE_FORMATTER;
import static org.apache.hadoop.ozone.s3.AWSSignatureProcessor.AWS4_SIGNING_ALGORITHM;
import static org.apache.hadoop.ozone.s3.AWSSignatureProcessor.DATE_FORMATTER;

/**
* S3 Authorization header.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.net.URI;

import org.apache.hadoop.ozone.s3.exception.OS3Exception;
import org.apache.hadoop.ozone.s3.header.AuthorizationHeaderV2;
import org.apache.hadoop.ozone.s3.header.AuthorizationHeaderV4;

import org.junit.Assert;
Expand All @@ -33,10 +34,10 @@
/**
* Test the Auth parser.
*/
public class TestAWSV4SignatureProcessor {
public class TestAWSSignatureProcessor {

@Test
public void testInitialization() throws Exception {
public void testV4Initialization() throws Exception {

MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
headers.putSingle("Content-Length", "123");
Expand Down Expand Up @@ -76,7 +77,7 @@ public void validateDateRange() throws OS3Exception {
Mockito.when(mock.getMethod()).thenReturn("GET");
Mockito.when(mock.getUriInfo()).thenReturn(uriInfo);

AWSV4SignatureProcessor parser = new AWSV4SignatureProcessor() {
AWSSignatureProcessor parser = new AWSSignatureProcessor() {
@Override
void validateSignedHeader(String header, String headerValue)
throws OS3Exception {
Expand All @@ -100,4 +101,41 @@ void validateSignedHeader(String header, String headerValue)
"f20d4de80af2271545385e8d4c7df608cae70a791c69b97aab1527ed93a0d665",
parser.getStringToSign());
}

@Test
public void testV2Initialization() throws Exception {

MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
String authHeader = "AWS root:ixWQAgWvJDuqLUqgDG9o4b2HF7c=";
headers.putSingle("Authorization", authHeader);

AuthorizationHeaderV2 parserAuthHeader =
new AuthorizationHeaderV2(authHeader);

MultivaluedMap<String, String> queryParameters = new MultivaluedHashMap<>();

UriInfo uriInfo = Mockito.mock(UriInfo.class);
Mockito.when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
Mockito.when(uriInfo.getRequestUri())
.thenReturn(new URI("http://localhost/buckets"));

ContainerRequestContext mock = Mockito.mock(ContainerRequestContext.class);
Mockito.when(mock.getHeaders()).thenReturn(headers);
Mockito.when(mock.getMethod()).thenReturn("GET");
Mockito.when(mock.getUriInfo()).thenReturn(uriInfo);

AWSSignatureProcessor parser = new AWSSignatureProcessor() {
@Override
void validateSignedHeader(String header, String headerValue)
throws OS3Exception {
super.validateSignedHeader(header, headerValue);
}
};
parser.setV2Header(parserAuthHeader);
parser.setContext(mock);
parser.init();

Assert.assertEquals("root", parser.getAwsAccessId());
Assert.assertEquals("ixWQAgWvJDuqLUqgDG9o4b2HF7c=", parser.getSignature());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import org.apache.hadoop.ozone.s3.exception.OS3Exception;

import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import static org.apache.hadoop.ozone.s3.AWSV4SignatureProcessor.DATE_FORMATTER;
import static org.apache.hadoop.ozone.s3.AWSSignatureProcessor.DATE_FORMATTER;
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.MALFORMED_HEADER;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import java.time.LocalDate;

import static java.time.temporal.ChronoUnit.DAYS;
import static org.apache.hadoop.ozone.s3.AWSV4SignatureProcessor.DATE_FORMATTER;
import static org.apache.hadoop.ozone.s3.AWSSignatureProcessor.DATE_FORMATTER;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

Expand Down