}
}
if (accessKey == null) {
logger.error("event=authenticate error_code=missing_access_key");
throw new AuthenticationException(CMBErrorCodes.InvalidAccessKeyId, "No access key provided");
}
User user = null;
try {
try {
user = userCacheByAccessKey.getAndSetIfNotPresent(accessKey, new UserCallableByAccessKey(accessKey), CMBProperties.getInstance().getUserCacheExpiring() * 1000);
} catch (CacheFullException e) {
user = new UserCallableByAccessKey(accessKey).call();
}
if (user == null) {
logger.error("event=authenticate access_key=" + accessKey + " error_code=invalid_accesskey");
throw new AuthenticationException(CMBErrorCodes.InvalidAccessKeyId, "AccessKey " + accessKey + " is not valid");
}
} catch (Exception ex) {
logger.error("event=authenticate", ex);
throw new AuthenticationException(CMBErrorCodes.InvalidAccessKeyId, "AccessKey " + accessKey + " is not valid");
}
// admin actions do not require signatures but can only be performed by admin user
if (ADMIN_ACTIONS.contains(parameters.get("Action"))) {
if (CMBProperties.getInstance().getCNSUserName().equals(user.getUserName())) {
logger.debug("event=authenticate action=admin_action");
return user;
} else {
logger.error("event=authenticate error_code=regular_user_attempted_admin_op");
throw new AuthenticationException(CMBErrorCodes.InvalidAccessKeyId, "User not authorized to perform admin actions");
}
}
if ((!CMBProperties.getInstance().getEnableSignatureAuth())||
(request.getMethod().equals("GET")&&CMBProperties.getInstance().getAllowGetRequest())) {
if (!user.getUserName().equals(CMBProperties.getInstance().getCNSUserName())) {
logger.debug("event=authenticate verify_signature=not_required");
}
return user;
}
//version 1 and 2 is from parameters
String version = parameters.get("SignatureVersion");
//version 4 is recommended from header
if((version == null)&&(authorizationHeader != null)){
if(authorizationHeader.trim().startsWith("AWS4")){
version="4";
}
}
if (!version.equals("1") && !version.equals("2")&&!version.equals("4")) {
logger.error("event=authenticate signature_version="+version+" error_code=unsupported_signature_version");
throw new AuthenticationException(CMBErrorCodes.NoSuchVersion, "SignatureVersion="+version+" is not valid");
}
//validate signature for version 1 and 2
if (version.equals("1")||version.equals("2")){
String signatureToCheck = parameters.get("Signature");
if (signatureToCheck == null) {
logger.error("event=authenticate error_code=no_signature_provided");
throw new AuthenticationException(CMBErrorCodes.MissingParameter, "Signature not found");
}
String timeStamp = parameters.get("Timestamp");
String expiration = parameters.get("Expires");
if (timeStamp != null) {
AuthUtil.checkTimeStamp(timeStamp);
} else if (expiration != null) {
AuthUtil.checkExpiration(expiration);
} else {
logger.error("event=authenticate error_code=no_time_stamp_or_expiration");
throw new AuthenticationException(CMBErrorCodes.MissingParameter, "Request must provide either Timestamp or Expires parameter");
}
String signatureMethod = parameters.get("SignatureMethod");
if (!signatureMethod.equals("HmacSHA256") && !signatureMethod.equals("HmacSHA1")) {
logger.error("event=authenticate signature_method=" + signatureMethod + " error_code=unsupported_signature_method");
throw new AuthenticationException(CMBErrorCodes.InvalidParameterValue, "Signature method " + signatureMethod + " is not supported");
}
URL url = null;
String signature = null;
try {
url = new URL(request.getRequestURL().toString());
parameters.remove("Signature");
signature = AuthUtil.generateSignature(url, parameters, version, signatureMethod, user.getAccessSecret());
} catch (Exception ex) {
logger.error("event=authenticate url="+url+" error_code=invalid_url");
throw new AuthenticationException(CMBErrorCodes.InternalError, "Invalid Url " + url);
}
if (signature == null || !signature.equals(signatureToCheck)) {
logger.error("event=authenticate signature_calculated=" + signature + " signature_given=" + signatureToCheck + " error_code=signature_mismatch");
throw new AuthenticationException(CMBErrorCodes.InvalidSignature, "Invalid signature");
}
}
//validate signature for version 4
if (version.equals("4")){
//get the signature from head
String signatureToCheck = authorizationHeader.substring(authorizationHeader.indexOf("Signature=") + "Signature=".length());
if (signatureToCheck == null) {
logger.error("event=authenticate error_code=no_signature_provided");
throw new AuthenticationException(CMBErrorCodes.MissingParameter, "Signature not found");
}
String timeStamp = request.getHeader("X-Amz-Date");
if (timeStamp != null) {
AuthUtil.checkTimeStampV4(timeStamp);
} else {
logger.error("event=authenticate error_code=no_time_stamp_or_expiration");
throw new AuthenticationException(CMBErrorCodes.MissingParameter, "Request must provide either Timestamp or Expires parameter");
}
String signatureMethod = authorizationHeader.substring("AWS4-".length(), authorizationHeader.indexOf("Credential=")).trim();
//currently support HMAC-SHA256
if (!signatureMethod.equals("HMAC-SHA256")) {
logger.error("event=authenticate signature_method=" + signatureMethod + " error_code=unsupported_signature_method");
throw new AuthenticationException(CMBErrorCodes.InvalidParameterValue, "Signature method " + signatureMethod + " is not supported");
}
URL url = null;
String signature = null;
try {
String urlOriginal=request.getRequestURL().toString();
if(urlOriginal==null || urlOriginal.length()==0){
urlOriginal="/";
}
url = new URL(urlOriginal);
signature = AuthUtil.generateSignatureV4(request, url, parameters, headers, version, signatureMethod, user.getAccessSecret());
} catch (Exception ex) {
logger.error("event=authenticate url="+url+" error_code=invalid_url");
throw new AuthenticationException(CMBErrorCodes.InternalError, "Invalid Url " + url);
}
if (signature == null || !signature.equals(signatureToCheck)) {
logger.error("event=authenticate signature_calculated=" + signature + " signature_given=" + signatureToCheck + " error_code=signature_mismatch");
throw new AuthenticationException(CMBErrorCodes.InvalidSignature, "Invalid signature");
}
}
logger.debug("event=authenticated_by_signature username=" + user.getUserName());
return user;