add some unit test for dubbo-auth (#5547)
This commit is contained in:
parent
5e85623c97
commit
8bf918ff67
|
|
@ -17,9 +17,10 @@
|
|||
package org.apache.dubbo.auth;
|
||||
|
||||
import org.apache.dubbo.auth.exception.AccessKeyNotFoundException;
|
||||
import org.apache.dubbo.auth.exception.RpcAuthenticationException;
|
||||
import org.apache.dubbo.auth.model.AccessKeyPair;
|
||||
import org.apache.dubbo.auth.spi.AccessKeyStorage;
|
||||
import org.apache.dubbo.auth.spi.AuthenticationHelper;
|
||||
import org.apache.dubbo.auth.spi.Authenticator;
|
||||
import org.apache.dubbo.auth.utils.SignatureUtils;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
|
|
@ -27,20 +28,20 @@ import org.apache.dubbo.common.extension.ExtensionLoader;
|
|||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
|
||||
public class AccessKeyAuthenticationHelper implements AuthenticationHelper {
|
||||
public class AccessKeyAuthenticator implements Authenticator {
|
||||
@Override
|
||||
public void signForRequest(Invocation invocation, URL url) {
|
||||
public void sign(Invocation invocation, URL url) {
|
||||
String currentTime = String.valueOf(System.currentTimeMillis());
|
||||
String consumer = url.getParameter(CommonConstants.APPLICATION_KEY);
|
||||
AccessKeyPair accessKeyPair = getAccessKeyPair(invocation, url);
|
||||
invocation.setAttachment(Constants.SIGNATURE_STRING_FORMAT, getSignature(url, invocation, accessKeyPair.getSecretKey(), currentTime));
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authenticateRequest(Invocation invocation, URL url) {
|
||||
public void authenticate(Invocation invocation, URL url) throws RpcAuthenticationException {
|
||||
String accessKeyId = String.valueOf(invocation.getAttachment(Constants.AK_KEY));
|
||||
String requestTimestamp = String.valueOf(invocation.getAttachment(Constants.REQUEST_TIMESTAMP_KEY));
|
||||
String originSignature = String.valueOf(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY));
|
||||
|
|
@ -48,19 +49,22 @@ public class AccessKeyAuthenticationHelper implements AuthenticationHelper {
|
|||
|
||||
if (StringUtils.isEmpty(accessKeyId) || StringUtils.isEmpty(consumer)
|
||||
|| StringUtils.isEmpty(requestTimestamp) || StringUtils.isEmpty(originSignature)) {
|
||||
throw new RuntimeException("Auth failed, maybe consumer not enable the auth");
|
||||
throw new RpcAuthenticationException("Failed to authenticate, maybe consumer not enable the auth");
|
||||
}
|
||||
AccessKeyPair accessKeyPair = null;
|
||||
try {
|
||||
accessKeyPair = getAccessKeyPair(invocation, url);
|
||||
} catch (Exception e) {
|
||||
throw new RpcAuthenticationException("Failed to authenticate , can't load the accessKeyPair", e);
|
||||
}
|
||||
AccessKeyPair accessKeyPair = getAccessKeyPair(invocation, url);
|
||||
|
||||
String computeSignature = getSignature(url, invocation, accessKeyPair.getSecretKey(), requestTimestamp);
|
||||
boolean success = computeSignature.equals(originSignature);
|
||||
if (!success) {
|
||||
throw new RuntimeException("Auth failed, signature is not correct");
|
||||
throw new RpcAuthenticationException("Failed to authenticate, signature is not correct");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
AccessKeyPair getAccessKeyPair(Invocation invocation, URL url) {
|
||||
AccessKeyStorage accessKeyStorage = ExtensionLoader.getExtensionLoader(AccessKeyStorage.class)
|
||||
.getExtension(url.getParameter(Constants.ACCESS_KEY_STORAGE_KEY, Constants.DEFAULT_ACCESS_KEY_STORAGE));
|
||||
|
|
@ -78,7 +82,7 @@ public class AccessKeyAuthenticationHelper implements AuthenticationHelper {
|
|||
}
|
||||
|
||||
String getSignature(URL url, Invocation invocation, String secrectKey, String time) {
|
||||
boolean parameterEncrypt = url.getParameter(Constants.PARAMTER_ENCRYPT_ENABLE_KEY, false);
|
||||
boolean parameterEncrypt = url.getParameter(Constants.PARAMTER_SIGNATURE_ENABLE_KEY, false);
|
||||
String signature;
|
||||
String requestString = String.format(Constants.SIGNATURE_STRING_FORMAT,
|
||||
url.getColonSeparatedKey(), invocation.getMethodName(), secrectKey, time);
|
||||
|
|
@ -18,13 +18,12 @@ package org.apache.dubbo.auth;
|
|||
|
||||
|
||||
public interface Constants {
|
||||
String REFERENCE_AUTH = "reference.auth";
|
||||
|
||||
String SERVICE_AUTH = "service.auth";
|
||||
String SERVICE_AUTH = "auth";
|
||||
|
||||
String AUTH_HELPER = "auth.helper";
|
||||
String AUTHENTICATOR = "authenticator";
|
||||
|
||||
String DEFAULT_AUTH_HELPER = "accesskey";
|
||||
String DEFAULT_AUTHENTICATOR = "accesskey";
|
||||
|
||||
String DEFAULT_ACCESS_KEY_STORAGE = "urlstorage";
|
||||
|
||||
|
|
@ -42,5 +41,5 @@ public interface Constants {
|
|||
|
||||
String SIGNATURE_STRING_FORMAT = "%s#%s#%s#%s";
|
||||
|
||||
String PARAMTER_ENCRYPT_ENABLE_KEY = "paramater.sign";
|
||||
String PARAMTER_SIGNATURE_ENABLE_KEY = "param.sign";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.auth.exception;
|
||||
|
||||
|
||||
public class RpcAuthenticationException extends Exception {
|
||||
public RpcAuthenticationException() {
|
||||
}
|
||||
|
||||
public RpcAuthenticationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public RpcAuthenticationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
package org.apache.dubbo.auth.filter;
|
||||
|
||||
import org.apache.dubbo.auth.Constants;
|
||||
import org.apache.dubbo.auth.spi.AuthenticationHelper;
|
||||
import org.apache.dubbo.auth.spi.Authenticator;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
|
|
@ -39,11 +39,11 @@ public class ConsumerSignFilter implements Filter {
|
|||
@Override
|
||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||
URL url = invoker.getUrl();
|
||||
boolean shouldAuth = url.getParameter(Constants.REFERENCE_AUTH, false);
|
||||
boolean shouldAuth = url.getParameter(Constants.SERVICE_AUTH, false);
|
||||
if (shouldAuth) {
|
||||
AuthenticationHelper authenticationHelper = ExtensionLoader.getExtensionLoader(AuthenticationHelper.class)
|
||||
.getExtension(url.getParameter(Constants.AUTH_HELPER, Constants.DEFAULT_AUTH_HELPER));
|
||||
authenticationHelper.signForRequest(invocation, url);
|
||||
Authenticator authenticator = ExtensionLoader.getExtensionLoader(Authenticator.class)
|
||||
.getExtension(url.getParameter(Constants.AUTHENTICATOR, Constants.DEFAULT_AUTHENTICATOR));
|
||||
authenticator.sign(invocation, url);
|
||||
}
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@
|
|||
*/
|
||||
package org.apache.dubbo.auth.filter;
|
||||
|
||||
import org.apache.dubbo.auth.spi.AuthenticationHelper;
|
||||
import org.apache.dubbo.auth.Constants;
|
||||
import org.apache.dubbo.auth.spi.Authenticator;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
import org.apache.dubbo.auth.Constants;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
|
@ -37,18 +37,12 @@ public class ProviderAuthFilter implements Filter {
|
|||
URL url = invoker.getUrl();
|
||||
boolean shouldAuth = url.getParameter(Constants.SERVICE_AUTH, false);
|
||||
if (shouldAuth) {
|
||||
AuthenticationHelper authenticationHelper = ExtensionLoader.getExtensionLoader(AuthenticationHelper.class)
|
||||
.getExtension(url.getParameter(Constants.AUTH_HELPER, Constants.DEFAULT_AUTH_HELPER));
|
||||
boolean authResult = false;
|
||||
Authenticator authenticator = ExtensionLoader.getExtensionLoader(Authenticator.class)
|
||||
.getExtension(url.getParameter(Constants.AUTHENTICATOR, Constants.DEFAULT_AUTHENTICATOR));
|
||||
try {
|
||||
authResult = authenticationHelper.authenticateRequest(invocation, url);
|
||||
if (!authResult) {
|
||||
SecurityException securityException = new SecurityException("Authenticate Request failed");
|
||||
return AsyncRpcResult.newDefaultAsyncResult(securityException, invocation);
|
||||
}
|
||||
authenticator.authenticate(invocation, url);
|
||||
} catch (Exception e) {
|
||||
SecurityException securityException = new SecurityException("Authenticate Request failed,", e);
|
||||
return AsyncRpcResult.newDefaultAsyncResult(securityException, invocation);
|
||||
return AsyncRpcResult.newDefaultAsyncResult(e, invocation);
|
||||
}
|
||||
}
|
||||
return invoker.invoke(invocation);
|
||||
|
|
|
|||
|
|
@ -17,12 +17,13 @@
|
|||
package org.apache.dubbo.auth.spi;
|
||||
|
||||
|
||||
import org.apache.dubbo.auth.exception.RpcAuthenticationException;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
|
||||
@SPI("accessKey")
|
||||
public interface AuthenticationHelper {
|
||||
public interface Authenticator {
|
||||
|
||||
/**
|
||||
* give a sign to request
|
||||
|
|
@ -30,14 +31,14 @@ public interface AuthenticationHelper {
|
|||
* @param invocation
|
||||
* @param url
|
||||
*/
|
||||
void signForRequest(Invocation invocation, URL url);
|
||||
void sign(Invocation invocation, URL url);
|
||||
|
||||
|
||||
/**
|
||||
* verify the signature of the request is valid or not
|
||||
*
|
||||
* @param invocation
|
||||
* @param url
|
||||
* @return true if the signature is valid
|
||||
* @throws RpcAuthenticationException when failed to authenticate current invocation
|
||||
*/
|
||||
boolean authenticateRequest(Invocation invocation, URL url);
|
||||
void authenticate(Invocation invocation, URL url) throws RpcAuthenticationException;
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
accesskey=org.apache.dubbo.auth.AccessKeyAuthenticationHelper
|
||||
|
|
@ -0,0 +1 @@
|
|||
accesskey=org.apache.dubbo.auth.AccessKeyAuthenticator
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.auth;
|
||||
|
||||
import org.apache.dubbo.auth.exception.RpcAuthenticationException;
|
||||
import org.apache.dubbo.auth.model.AccessKeyPair;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
class AccessKeyAuthenticatorTest {
|
||||
|
||||
@Test
|
||||
void testSignForRequest() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk");
|
||||
Invocation invocation = new RpcInvocation();
|
||||
|
||||
AccessKeyAuthenticator helper = mock(AccessKeyAuthenticator.class);
|
||||
doCallRealMethod().when(helper).sign(invocation, url);
|
||||
when(helper.getSignature(eq(url), eq(invocation), eq("sk"), anyString())).thenReturn("dubbo");
|
||||
|
||||
AccessKeyPair accessKeyPair = mock(AccessKeyPair.class);
|
||||
when(accessKeyPair.getSecretKey()).thenReturn("sk");
|
||||
when(helper.getAccessKeyPair(invocation, url)).thenReturn(accessKeyPair);
|
||||
|
||||
helper.sign(invocation, url);
|
||||
assertEquals(String.valueOf(invocation.getAttachment(CommonConstants.CONSUMER)), url.getParameter(CommonConstants.APPLICATION_KEY));
|
||||
assertNotNull(invocation.getAttachments().get(Constants.REQUEST_SIGNATURE_KEY));
|
||||
assertEquals(invocation.getAttachments().get(Constants.REQUEST_SIGNATURE_KEY), "dubbo");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthenticateRequest() throws RpcAuthenticationException {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk");
|
||||
Invocation invocation = new RpcInvocation();
|
||||
invocation.setAttachment(Constants.ACCESS_KEY_ID_KEY, "ak");
|
||||
invocation.setAttachment(Constants.REQUEST_SIGNATURE_KEY, "dubbo");
|
||||
invocation.setAttachment(Constants.REQUEST_TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
|
||||
invocation.setAttachment(CommonConstants.CONSUMER, "test");
|
||||
|
||||
AccessKeyAuthenticator helper = mock(AccessKeyAuthenticator.class);
|
||||
doCallRealMethod().when(helper).authenticate(invocation, url);
|
||||
when(helper.getSignature(eq(url), eq(invocation), eq("sk"), anyString())).thenReturn("dubbo");
|
||||
|
||||
AccessKeyPair accessKeyPair = mock(AccessKeyPair.class);
|
||||
when(accessKeyPair.getSecretKey()).thenReturn("sk");
|
||||
when(helper.getAccessKeyPair(invocation, url)).thenReturn(accessKeyPair);
|
||||
|
||||
assertDoesNotThrow(() -> helper.authenticate(invocation, url));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthenticateRequestNoSignature() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk");
|
||||
Invocation invocation = new RpcInvocation();
|
||||
AccessKeyAuthenticator helper = new AccessKeyAuthenticator();
|
||||
assertThrows(RpcAuthenticationException.class, () -> helper.authenticate(invocation, url));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAccessKeyPairFailed() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak");
|
||||
AccessKeyAuthenticator helper = new AccessKeyAuthenticator();
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
assertThrows(RuntimeException.class, () -> helper.getAccessKeyPair(invocation, url));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSignatureNoParameter() {
|
||||
URL url = mock(URL.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
String secretKey = "123456";
|
||||
AccessKeyAuthenticator helper = new AccessKeyAuthenticator();
|
||||
String signature = helper.getSignature(url, invocation, secretKey, String.valueOf(System.currentTimeMillis()));
|
||||
assertNotNull(signature);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSignatureWithParameter() {
|
||||
URL url = mock(URL.class);
|
||||
when(url.getParameter(Constants.PARAMTER_SIGNATURE_ENABLE_KEY, false)).thenReturn(true);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
String secretKey = "123456";
|
||||
Object[] params = {"dubbo", new ArrayList()};
|
||||
when(invocation.getArguments()).thenReturn(params);
|
||||
AccessKeyAuthenticator helper = new AccessKeyAuthenticator();
|
||||
String signature = helper.getSignature(url, invocation, secretKey, String.valueOf(System.currentTimeMillis()));
|
||||
assertNotNull(signature);
|
||||
|
||||
Object[] fakeParams = {"dubbo1", new ArrayList<>()};
|
||||
when(invocation.getArguments()).thenReturn(fakeParams);
|
||||
String signature1 = helper.getSignature(url, invocation, secretKey, String.valueOf(System.currentTimeMillis()));
|
||||
assertNotEquals(signature, signature1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.auth;
|
||||
|
||||
import org.apache.dubbo.auth.model.AccessKeyPair;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
|
||||
class DefaultAccessKeyStorageTest {
|
||||
|
||||
@Test
|
||||
void testGetAccessKey() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk");
|
||||
DefaultAccessKeyStorage defaultAccessKeyStorage = new DefaultAccessKeyStorage();
|
||||
AccessKeyPair accessKey = defaultAccessKeyStorage.getAccessKey(url, mock(Invocation.class));
|
||||
assertNotNull(accessKey);
|
||||
assertEquals(accessKey.getAccessKey(), "ak");
|
||||
assertEquals(accessKey.getSecretKey(), "sk");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.auth.filter;
|
||||
|
||||
import org.apache.dubbo.auth.Constants;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
class ConsumerSignFilterTest {
|
||||
|
||||
@Test
|
||||
void testAuthDisabled() {
|
||||
URL url = mock(URL.class);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
ConsumerSignFilter consumerSignFilter = new ConsumerSignFilter();
|
||||
consumerSignFilter.invoke(invoker, invocation);
|
||||
verify(invocation, never()).setAttachment(eq(Constants.REQUEST_SIGNATURE_KEY), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthEnabled() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test")
|
||||
.addParameter(Constants.SERVICE_AUTH, true);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
ConsumerSignFilter consumerSignFilter = new ConsumerSignFilter();
|
||||
consumerSignFilter.invoke(invoker, invocation);
|
||||
verify(invocation, times(1)).setAttachment(eq(Constants.REQUEST_SIGNATURE_KEY), anyString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.auth.filter;
|
||||
|
||||
import org.apache.dubbo.auth.Constants;
|
||||
import org.apache.dubbo.auth.exception.RpcAuthenticationException;
|
||||
import org.apache.dubbo.auth.utils.SignatureUtils;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
class ProviderAuthFilterTest {
|
||||
@Test
|
||||
void testAuthDisabled() {
|
||||
URL url = mock(URL.class);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
|
||||
providerAuthFilter.invoke(invoker, invocation);
|
||||
verify(url, never()).getParameter(eq(Constants.AUTHENTICATOR), eq(Constants.DEFAULT_AUTHENTICATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthEnabled() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test")
|
||||
.addParameter(Constants.SERVICE_AUTH, true);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
|
||||
providerAuthFilter.invoke(invoker, invocation);
|
||||
verify(invocation, atLeastOnce()).getAttachment(anyString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testAuthFailed() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test")
|
||||
.addParameter(Constants.SERVICE_AUTH, true);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn(null);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
|
||||
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
|
||||
Result result = providerAuthFilter.invoke(invoker, invocation);
|
||||
assertTrue(result.hasException());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthFailedWhenNoSignature() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test")
|
||||
.addParameter(Constants.SERVICE_AUTH, true);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn(null);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
|
||||
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
|
||||
Result result = providerAuthFilter.invoke(invoker, invocation);
|
||||
assertTrue(result.hasException());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthFailedWhenNoAccessKeyPair() {
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test-provider")
|
||||
.addParameter(Constants.SERVICE_AUTH, true);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn("dubbo");
|
||||
when(invocation.getAttachment(Constants.AK_KEY)).thenReturn("ak");
|
||||
when(invocation.getAttachment(CommonConstants.CONSUMER)).thenReturn("test-consumer");
|
||||
when(invocation.getAttachment(Constants.REQUEST_TIMESTAMP_KEY)).thenReturn(System.currentTimeMillis());
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
|
||||
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
|
||||
Result result = providerAuthFilter.invoke(invoker, invocation);
|
||||
assertTrue(result.hasException());
|
||||
assertTrue(result.getException() instanceof RpcAuthenticationException);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthFailedWhenParameterError() {
|
||||
String service = "org.apache.dubbo.DemoService";
|
||||
String method = "test";
|
||||
Object[] originalParams = new Object[]{"dubbo1", "dubbo2"};
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.setServiceInterface(service)
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test-provider")
|
||||
.addParameter(Constants.PARAMTER_SIGNATURE_ENABLE_KEY, true)
|
||||
.addParameter(Constants.SERVICE_AUTH, true);
|
||||
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invocation.getAttachment(Constants.AK_KEY)).thenReturn("ak");
|
||||
when(invocation.getAttachment(CommonConstants.CONSUMER)).thenReturn("test-consumer");
|
||||
when(invocation.getAttachment(Constants.REQUEST_TIMESTAMP_KEY)).thenReturn(currentTimeMillis);
|
||||
when(invocation.getMethodName()).thenReturn(method);
|
||||
Object[] fakeParams = new Object[]{"dubbo1", "dubbo3"};
|
||||
when(invocation.getArguments()).thenReturn(fakeParams);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
|
||||
|
||||
String requestString = String.format(Constants.SIGNATURE_STRING_FORMAT,
|
||||
url.getColonSeparatedKey(), invocation.getMethodName(), "sk", currentTimeMillis);
|
||||
String sign = SignatureUtils.sign(originalParams, requestString, "sk");
|
||||
when(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn(sign);
|
||||
|
||||
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
|
||||
Result result = providerAuthFilter.invoke(invoker, invocation);
|
||||
assertTrue(result.hasException());
|
||||
assertTrue(result.getException() instanceof RpcAuthenticationException);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthSuccessfully() {
|
||||
String service = "org.apache.dubbo.DemoService";
|
||||
String method = "test";
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
|
||||
.setServiceInterface(service)
|
||||
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak")
|
||||
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk")
|
||||
.addParameter(CommonConstants.APPLICATION_KEY, "test-provider")
|
||||
.addParameter(Constants.SERVICE_AUTH, true);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
Invocation invocation = mock(Invocation.class);
|
||||
when(invocation.getAttachment(Constants.AK_KEY)).thenReturn("ak");
|
||||
when(invocation.getAttachment(CommonConstants.CONSUMER)).thenReturn("test-consumer");
|
||||
when(invocation.getAttachment(Constants.REQUEST_TIMESTAMP_KEY)).thenReturn(currentTimeMillis);
|
||||
when(invocation.getMethodName()).thenReturn(method);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
|
||||
|
||||
String requestString = String.format(Constants.SIGNATURE_STRING_FORMAT,
|
||||
url.getColonSeparatedKey(), invocation.getMethodName(), "sk", currentTimeMillis);
|
||||
String sign = SignatureUtils.sign(requestString, "sk");
|
||||
when(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn(sign);
|
||||
|
||||
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
|
||||
Result result = providerAuthFilter.invoke(invoker, invocation);
|
||||
assertNull(result);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue