diff --git a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/AccessKeyAuthenticator.java b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/AccessKeyAuthenticator.java index b8ee2f6eda..bddd67c401 100644 --- a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/AccessKeyAuthenticator.java +++ b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/AccessKeyAuthenticator.java @@ -38,12 +38,11 @@ public class AccessKeyAuthenticator implements Authenticator { @Override public void sign(Invocation invocation, URL url) { String currentTime = String.valueOf(System.currentTimeMillis()); - String consumer = url.getApplication(); AccessKeyPair accessKeyPair = getAccessKeyPair(invocation, url); invocation.setAttachment(Constants.REQUEST_SIGNATURE_KEY, getSignature(url, invocation, accessKeyPair.getSecretKey(), currentTime)); invocation.setAttachment(Constants.REQUEST_TIMESTAMP_KEY, currentTime); invocation.setAttachment(Constants.AK_KEY, accessKeyPair.getAccessKey()); - invocation.setAttachment(CommonConstants.CONSUMER, consumer); + invocation.setAttachment(CommonConstants.CONSUMER, url.getApplication()); } @Override @@ -52,12 +51,11 @@ public class AccessKeyAuthenticator implements Authenticator { String requestTimestamp = String.valueOf(invocation.getAttachment(Constants.REQUEST_TIMESTAMP_KEY)); String originSignature = String.valueOf(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)); String consumer = String.valueOf(invocation.getAttachment(CommonConstants.CONSUMER)); - - if (StringUtils.isEmpty(accessKeyId) || StringUtils.isEmpty(consumer) - || StringUtils.isEmpty(requestTimestamp) || StringUtils.isEmpty(originSignature)) { - throw new RpcAuthenticationException("Failed to authenticate, maybe consumer not enable the auth"); + if (StringUtils.isAnyEmpty(accessKeyId, consumer, requestTimestamp, originSignature)) { + throw new RpcAuthenticationException("Failed to authenticate, maybe consumer side did not enable the auth"); } - AccessKeyPair accessKeyPair = null; + + AccessKeyPair accessKeyPair; try { accessKeyPair = getAccessKeyPair(invocation, url); } catch (Exception e) { @@ -75,10 +73,10 @@ public class AccessKeyAuthenticator implements Authenticator { AccessKeyStorage accessKeyStorage = applicationModel.getExtensionLoader(AccessKeyStorage.class) .getExtension(url.getParameter(Constants.ACCESS_KEY_STORAGE_KEY, Constants.DEFAULT_ACCESS_KEY_STORAGE)); - AccessKeyPair accessKeyPair = null; + AccessKeyPair accessKeyPair; try { accessKeyPair = accessKeyStorage.getAccessKey(url, invocation); - if (accessKeyPair == null || StringUtils.isEmpty(accessKeyPair.getAccessKey()) || StringUtils.isEmpty(accessKeyPair.getSecretKey())) { + if (accessKeyPair == null || StringUtils.isAnyEmpty(accessKeyPair.getAccessKey(), accessKeyPair.getSecretKey())) { throw new AccessKeyNotFoundException("AccessKeyId or secretAccessKey not found"); } } catch (Exception e) { @@ -88,16 +86,11 @@ public class AccessKeyAuthenticator implements Authenticator { } String getSignature(URL url, Invocation invocation, String secretKey, String time) { + String requestString = String.format(Constants.SIGNATURE_STRING_FORMAT, url.getColonSeparatedKey(), invocation.getMethodName(), secretKey, time); boolean parameterEncrypt = url.getParameter(Constants.PARAMETER_SIGNATURE_ENABLE_KEY, false); - String signature; - String requestString = String.format(Constants.SIGNATURE_STRING_FORMAT, - url.getColonSeparatedKey(), invocation.getMethodName(), secretKey, time); if (parameterEncrypt) { - signature = SignatureUtils.sign(invocation.getArguments(), requestString, secretKey); - } else { - signature = SignatureUtils.sign(requestString, secretKey); + return SignatureUtils.sign(invocation.getArguments(), requestString, secretKey); } - return signature; + return SignatureUtils.sign(requestString, secretKey); } - } diff --git a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/utils/SignatureUtils.java b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/utils/SignatureUtils.java index 7b8b6015fb..babe23c6b9 100644 --- a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/utils/SignatureUtils.java +++ b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/utils/SignatureUtils.java @@ -23,75 +23,68 @@ import java.io.IOException; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.security.SignatureException; -import java.util.Arrays; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.Base64; public class SignatureUtils { private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256"; - public static String sign(String metadata, String key) throws SecurityException { - try { - return sign(metadata.getBytes(), key); - } catch (Exception e) { - throw new SecurityException("Failed to generate HMAC : " + e.getMessage(), e); - } + public static String sign(String metadata, String key) throws RuntimeException { + return sign(metadata.getBytes(StandardCharsets.UTF_8), key); } - public static String sign(Object[] parameters, String metadata, String key) { - try { - if (parameters == null) { - return sign(metadata, key); - } - boolean notSerializable = Arrays.stream(parameters).anyMatch(parameter -> !(parameter instanceof Serializable)); - if (notSerializable) { - throw new IllegalArgumentException(""); - } - - Object[] includeMetadata = new Object[parameters.length + 1]; - System.arraycopy(parameters, 0, includeMetadata, 0, parameters.length); - includeMetadata[parameters.length] = metadata; - byte[] bytes = toByteArray(includeMetadata); - return sign(bytes, key); - } catch (Exception e) { - throw new SecurityException("Failed to generate HMAC : " + e.getMessage(), e); + public static String sign(Object[] parameters, String metadata, String key) throws RuntimeException { + if (parameters == null) { + return sign(metadata, key); } + for (int i = 0; i < parameters.length; i++) { + if (!(parameters[i] instanceof Serializable)) { + throw new IllegalArgumentException("The parameter [" + i + "] to be signed was not serializable."); + } + } + Object[] includeMetadata = new Object[parameters.length + 1]; + System.arraycopy(parameters, 0, includeMetadata, 0, parameters.length); + includeMetadata[parameters.length] = metadata; + byte[] includeMetadataBytes; + try { + includeMetadataBytes = toByteArray(includeMetadata); + } catch (IOException e) { + throw new RuntimeException("Failed to generate HMAC: " + e.getMessage()); + } + return sign(includeMetadataBytes, key); } - public static String sign(byte[] data, String key) throws SignatureException { - String result; + private static String sign(byte[] data, String key) throws RuntimeException { + Mac mac; + try { + mac = Mac.getInstance(HMAC_SHA256_ALGORITHM); + } catch(NoSuchAlgorithmException e) { + throw new RuntimeException("Failed to generate HMAC: no such algorithm exception " + HMAC_SHA256_ALGORITHM); + } + SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA256_ALGORITHM); try { - Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM); - SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), - HMAC_SHA256_ALGORITHM); mac.init(signingKey); - // compute the hmac on input data bytes - byte[] rawHmac = mac.doFinal(data); - // base64-encode the hmac - result = Base64.getEncoder().encodeToString(rawHmac); - - } catch (Exception e) { - throw new SignatureException("Failed to generate HMAC : " - + e.getMessage()); + } catch(InvalidKeyException e) { + throw new RuntimeException("Failed to generate HMAC: invalid key exception"); } - return result; + byte[] rawHmac; + try{ + // compute the hmac on input data bytes + rawHmac = mac.doFinal(data); + } catch (IllegalStateException e) { + throw new RuntimeException("Failed to generate HMAC: " + e.getMessage()); + } + // base64-encode the hmac + return Base64.getEncoder().encodeToString(rawHmac); } - static byte[] toByteArray(Object[] parameters) throws Exception { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutput out = null; - try { - out = new ObjectOutputStream(bos); + private static byte[] toByteArray(Object[] parameters) throws IOException { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos)) { out.writeObject(parameters); out.flush(); return bos.toByteArray(); - } finally { - try { - bos.close(); - } catch (IOException ex) { - // ignore close exception - } } } - } diff --git a/dubbo-plugin/dubbo-auth/src/test/java/org/apache/dubbo/auth/AccessKeyAuthenticatorTest.java b/dubbo-plugin/dubbo-auth/src/test/java/org/apache/dubbo/auth/AccessKeyAuthenticatorTest.java index c12c3131d2..bc9b8f939b 100644 --- a/dubbo-plugin/dubbo-auth/src/test/java/org/apache/dubbo/auth/AccessKeyAuthenticatorTest.java +++ b/dubbo-plugin/dubbo-auth/src/test/java/org/apache/dubbo/auth/AccessKeyAuthenticatorTest.java @@ -133,6 +133,5 @@ class AccessKeyAuthenticatorTest { when(invocation.getArguments()).thenReturn(fakeParams); String signature1 = helper.getSignature(url, invocation, secretKey, String.valueOf(System.currentTimeMillis())); assertNotEquals(signature, signature1); - } } diff --git a/dubbo-plugin/dubbo-auth/src/test/java/org/apache/dubbo/auth/utils/SignatureUtilsTest.java b/dubbo-plugin/dubbo-auth/src/test/java/org/apache/dubbo/auth/utils/SignatureUtilsTest.java index 07d22b670b..d6bbae6e47 100644 --- a/dubbo-plugin/dubbo-auth/src/test/java/org/apache/dubbo/auth/utils/SignatureUtilsTest.java +++ b/dubbo-plugin/dubbo-auth/src/test/java/org/apache/dubbo/auth/utils/SignatureUtilsTest.java @@ -16,43 +16,23 @@ */ package org.apache.dubbo.auth.utils; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.util.ArrayList; -import java.util.List; public class SignatureUtilsTest { - - private Object[] objects = new Object[2]; - private List list = new ArrayList<>(); - private String temp = "temp"; - private String key = "TOKEN"; - - { - objects[0] = list; - objects[1] = temp; - } - @Test - void testObjectToByteArray() { - - try { - byte[] bytes = SignatureUtils.toByteArray(objects); - Assertions.assertNotEquals(0, bytes.length); - } catch (Exception e) { - e.printStackTrace(); - } + void testEncryptWithObject() { + Object[] objects = new Object[] {new ArrayList<>(), "temp"}; + String encryptWithObject = SignatureUtils.sign(objects, "TestMethod#hello", "TOKEN"); + Assertions.assertEquals(encryptWithObject, "t6c7PasKguovqSrVRcTQU4wTZt/ybl0jBCUMgAt/zQw="); } - + @Test - void testEncryptObject() { - String encrypt = SignatureUtils.sign(objects, "TestMethod#hello", key); - String encryptNoParams = SignatureUtils.sign(null, "TestMethod#hello", key); - Assertions.assertNotNull(encrypt); - Assertions.assertNotNull(encryptNoParams); - Assertions.assertNotEquals(encrypt, encryptNoParams); + void testEncryptWithNoParameters() { + String encryptWithNoParams = SignatureUtils.sign(null, "TestMethod#hello", "TOKEN"); + Assertions.assertEquals(encryptWithNoParams, "2DGkTcyXg4plU24rY8MZkEJwOMRW3o+wUP3HssRc3EE="); } }