Revise Auth server plugin (#6890)

This commit is contained in:
Wuyunfan-BUPT 2021-09-16 01:11:28 -05:00 committed by GitHub
parent b825bac845
commit af8d04f59b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 194 additions and 163 deletions

View File

@ -31,11 +31,10 @@ public interface AuthService {
* Authentication of request, identify the user who request the resource. * Authentication of request, identify the user who request the resource.
* *
* @param identityContext where we can find the user information * @param identityContext where we can find the user information
* @return boolean if the user identify success * @return IdentityContext user auth result
* @throws AccessException if authentication is failed * @throws AccessException if authentication is failed
*/ */
Boolean login(IdentityContext identityContext) throws AccessException; IdentityContext login(IdentityContext identityContext) throws AccessException;
/** /**
* identity whether the user has the resource authority. * identity whether the user has the resource authority.

View File

@ -46,12 +46,6 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
@JustForTest @JustForTest
private static Boolean cachingEnabled = null; private static Boolean cachingEnabled = null;
/**
* identifyContext position.
*/
@Value("${nacos.core.auth.identifyPosition:}")
private IdentifyPositionTypes identifyPosition;
/** /**
* Authority key set. * Authority key set.
*/ */
@ -107,10 +101,6 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
return secretKeyBytes; return secretKeyBytes;
} }
public IdentifyPositionTypes getIdentifyPositionTypes() {
return identifyPosition;
}
public String[] getAuthorityKey() { public String[] getAuthorityKey() {
return authorityKey; return authorityKey;
} }
@ -169,7 +159,6 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
serverIdentityKey = EnvUtil.getProperty("nacos.core.auth.server.identity.key", ""); serverIdentityKey = EnvUtil.getProperty("nacos.core.auth.server.identity.key", "");
serverIdentityValue = EnvUtil.getProperty("nacos.core.auth.server.identity.value", ""); serverIdentityValue = EnvUtil.getProperty("nacos.core.auth.server.identity.value", "");
enableUserAgentAuthWhite = EnvUtil.getProperty("nacos.core.auth.enable.userAgentAuthWhite", Boolean.class, false); enableUserAgentAuthWhite = EnvUtil.getProperty("nacos.core.auth.enable.userAgentAuthWhite", Boolean.class, false);
identifyPosition = IdentifyPositionTypes.valueOf(EnvUtil.getProperty("nacos.core.auth.identifyPosition", "HEADER_AND_PARAMETER"));
authorityKey = EnvUtil.getProperty("nacos.core.auth.authorityKey", "").split(","); authorityKey = EnvUtil.getProperty("nacos.core.auth.authorityKey", "").split(",");
} catch (Exception e) { } catch (Exception e) {
LOGGER.warn("Upgrade auth config from env failed, use old value", e); LOGGER.warn("Upgrade auth config from env failed, use old value", e);

View File

@ -1,44 +0,0 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.auth.common;
public enum IdentifyPositionTypes {
/**
* Identify context in http request header.
*/
HEADER("HEADER"),
/**
* Identify context in http request parameter.
*/
PARAMETER("PARAMETER"),
/**
* Identify context in http request header and parameter..
*/
HEADER_AND_PARAMETER("HEADER_AND_PARAMETER");
private String position;
IdentifyPositionTypes(String position) {
this.position = position;
}
@Override
public String toString() {
return position;
}
}

View File

@ -25,7 +25,16 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
public class GrpcIdentityContextBuilder implements IdentityContextBuilder<Request> { public class GrpcIdentityContextBuilder implements IdentityContextBuilder<Request> {
AuthConfigs authConfigs = new AuthConfigs();
AuthConfigs authConfigs;
public GrpcIdentityContextBuilder() {
authConfigs = new AuthConfigs();
}
public GrpcIdentityContextBuilder(AuthConfigs authConfigs) {
this.authConfigs = authConfigs;
}
/** /**
* get identity context from grpc. * get identity context from grpc.
* @param request grpc request * @param request grpc request

View File

@ -17,7 +17,6 @@
package com.alibaba.nacos.auth.context; package com.alibaba.nacos.auth.context;
import com.alibaba.nacos.auth.common.AuthConfigs; import com.alibaba.nacos.auth.common.AuthConfigs;
import com.alibaba.nacos.auth.exception.AuthConfigsException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -30,11 +29,12 @@ public class HttpIdentityContextBuilder implements IdentityContextBuilder<HttpSe
private AuthConfigs authConfigs; private AuthConfigs authConfigs;
IdentityContext identityContext;
public HttpIdentityContextBuilder() { public HttpIdentityContextBuilder() {
authConfigs = new AuthConfigs(); authConfigs = new AuthConfigs();
identityContext = new IdentityContext(); }
public HttpIdentityContextBuilder(AuthConfigs authConfigs) {
this.authConfigs = authConfigs;
} }
/** /**
@ -44,36 +44,31 @@ public class HttpIdentityContextBuilder implements IdentityContextBuilder<HttpSe
* @return IdentityContext from request context * @return IdentityContext from request context
*/ */
@Override @Override
public IdentityContext build(HttpServletRequest request) throws AuthConfigsException { public IdentityContext build(HttpServletRequest request) {
switch (authConfigs.getIdentifyPositionTypes()) { IdentityContext identityContext = new IdentityContext();
case HEADER: Set<String> keySet = new HashSet<>(Arrays.asList(authConfigs.getAuthorityKey()));
Enumeration<String> headerEnu = request.getHeaderNames(); Enumeration<String> headerEnu = request.getHeaderNames();
setIdentityContext(headerEnu, request);
break; while (headerEnu.hasMoreElements()) {
case PARAMETER: String paraName = headerEnu.nextElement();
Enumeration<String> paramEnu = request.getParameterNames(); if (keySet.contains(paraName)) {
setIdentityContext(paramEnu, request); identityContext.setParameter(paraName, request.getHeader(paraName));
break; keySet.remove(paraName);
case HEADER_AND_PARAMETER:
Enumeration<String> headerBothEnu = request.getHeaderNames();
Enumeration<String> paramBothEnu = request.getParameterNames();
setIdentityContext(headerBothEnu, request);
setIdentityContext(paramBothEnu, request);
break;
default:
throw new AuthConfigsException("AuthConfigs.identifyPosition error! Check application.properties nacos.core.auth.identifyPosition.");
} }
}
if (keySet.isEmpty()) {
return identityContext; return identityContext;
} }
public void setIdentityContext(Enumeration<String> enu, HttpServletRequest request) { Enumeration<String> paramEnu = request.getParameterNames();
Set<String> keySet = new HashSet<String>(Arrays.asList(authConfigs.getAuthorityKey())); while (paramEnu.hasMoreElements()) {
while (enu.hasMoreElements()) { String paraName = paramEnu.nextElement();
String paraName = enu.nextElement();
if (keySet.contains(paraName)) { if (keySet.contains(paraName)) {
identityContext.setParameter(paraName, request.getParameter(paraName)); identityContext.setParameter(paraName, request.getParameter(paraName));
keySet.remove(paraName);
} }
} }
return identityContext;
} }
} }

View File

@ -16,8 +16,6 @@
package com.alibaba.nacos.auth.context; package com.alibaba.nacos.auth.context;
import com.alibaba.nacos.auth.exception.AuthConfigsException;
/** /**
* Identify context. * Identify context.
* *
@ -29,8 +27,7 @@ public interface IdentityContextBuilder<T> {
* build identity context from request. * build identity context from request.
* @param request user request * @param request user request
* @return IdentityContext from request context * @return IdentityContext from request context
* @throws AuthConfigsException if AuthConfigs is invalid
*/ */
IdentityContext build(T request) throws AuthConfigsException; IdentityContext build(T request);
} }

View File

@ -1,37 +0,0 @@
package com.alibaba.nacos.auth.exception;
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed 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.
*/
import com.alibaba.nacos.api.exception.NacosException;
/**
* AuthConfig exception.
*
* @author wuyfee
*/
public class AuthConfigsException extends NacosException {
public AuthConfigsException() {}
public AuthConfigsException(int code) {
this.setErrCode(code);
}
public AuthConfigsException(String msg) {
this.setErrMsg(msg);
}
}

View File

@ -39,8 +39,6 @@ public class AuthConfigsTest {
private static final boolean TEST_ENABLE_UA_WHITE = true; private static final boolean TEST_ENABLE_UA_WHITE = true;
private static final IdentifyPositionTypes IDENTIFYPOSITION = IdentifyPositionTypes.HEADER_AND_PARAMETER;
private static final String AUTHORITYKEY = "username,password,token,tenant"; private static final String AUTHORITYKEY = "username,password,token,tenant";
private AuthConfigs authConfigs; private AuthConfigs authConfigs;
@ -61,7 +59,6 @@ public class AuthConfigsTest {
environment.setProperty("nacos.core.auth.server.identity.key", TEST_SERVER_IDENTITY_KEY); environment.setProperty("nacos.core.auth.server.identity.key", TEST_SERVER_IDENTITY_KEY);
environment.setProperty("nacos.core.auth.server.identity.value", TEST_SERVER_IDENTITY_VALUE); environment.setProperty("nacos.core.auth.server.identity.value", TEST_SERVER_IDENTITY_VALUE);
environment.setProperty("nacos.core.auth.enable.userAgentAuthWhite", String.valueOf(TEST_ENABLE_UA_WHITE)); environment.setProperty("nacos.core.auth.enable.userAgentAuthWhite", String.valueOf(TEST_ENABLE_UA_WHITE));
environment.setProperty("nacos.core.auth.enable.identifyPosition", String.valueOf(IDENTIFYPOSITION));
environment.setProperty("nacos.core.auth.enable.authorityKey", AUTHORITYKEY); environment.setProperty("nacos.core.auth.enable.authorityKey", AUTHORITYKEY);
authConfigs.onEvent(ServerConfigChangeEvent.newEvent()); authConfigs.onEvent(ServerConfigChangeEvent.newEvent());
@ -70,7 +67,6 @@ public class AuthConfigsTest {
assertEquals(TEST_SERVER_IDENTITY_KEY, authConfigs.getServerIdentityKey()); assertEquals(TEST_SERVER_IDENTITY_KEY, authConfigs.getServerIdentityKey());
assertEquals(TEST_SERVER_IDENTITY_VALUE, authConfigs.getServerIdentityValue()); assertEquals(TEST_SERVER_IDENTITY_VALUE, authConfigs.getServerIdentityValue());
assertEquals(TEST_ENABLE_UA_WHITE, authConfigs.isEnableUserAgentAuthWhite()); assertEquals(TEST_ENABLE_UA_WHITE, authConfigs.isEnableUserAgentAuthWhite());
assertEquals(IDENTIFYPOSITION.toString(), authConfigs.getIdentifyPositionTypes().toString());
Assert.assertTrue(Arrays.equals(AUTHORITYKEY.split(","), authConfigs.getAuthorityKey())); Assert.assertTrue(Arrays.equals(AUTHORITYKEY.split(","), authConfigs.getAuthorityKey()));
} }
} }

View File

@ -19,7 +19,6 @@ package com.alibaba.nacos.auth.common;
import com.alibaba.nacos.auth.AuthPluginManager; import com.alibaba.nacos.auth.AuthPluginManager;
import com.alibaba.nacos.auth.AuthService; import com.alibaba.nacos.auth.AuthService;
import com.alibaba.nacos.auth.context.IdentityContext; import com.alibaba.nacos.auth.context.IdentityContext;
import com.alibaba.nacos.auth.exception.AccessException;
import com.alibaba.nacos.auth.model.Permission; import com.alibaba.nacos.auth.model.Permission;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -73,8 +72,7 @@ public class AuthPluginManagerTest {
} }
@Test @Test
public void testFindAuthServiceSpiImpl() throws AccessException { public void testFindAuthServiceSpiImpl() {
Mockito.when(authService.login(identityContext)).thenReturn(true);
Mockito.when(authService.authorityAccess(identityContext, permission)).thenReturn(true); Mockito.when(authService.authorityAccess(identityContext, permission)).thenReturn(true);
Mockito.when(authService.getAuthServiceName()).thenReturn(TYPE); Mockito.when(authService.getAuthServiceName()).thenReturn(TYPE);
Optional<AuthService> authServiceImpl = authPluginManager.findAuthServiceSpiImpl(TYPE); Optional<AuthService> authServiceImpl = authPluginManager.findAuthServiceSpiImpl(TYPE);

View File

@ -1,38 +1,173 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.auth.common; package com.alibaba.nacos.auth.common;
import com.alibaba.nacos.api.remote.request.ConnectionSetupRequest; import com.alibaba.nacos.api.remote.request.HealthCheckRequest;
import com.alibaba.nacos.auth.context.GrpcIdentityContextBuilder; import com.alibaba.nacos.auth.context.GrpcIdentityContextBuilder;
import com.alibaba.nacos.auth.context.HttpIdentityContextBuilder; import com.alibaba.nacos.auth.context.HttpIdentityContextBuilder;
import com.alibaba.nacos.auth.exception.AuthConfigsException; import com.alibaba.nacos.auth.context.IdentityContext;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import com.alibaba.nacos.api.remote.request.Request; import com.alibaba.nacos.api.remote.request.Request;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Vector;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class IdentityContextBuilderTest { public class IdentityContextBuilderTest {
HttpIdentityContextBuilder httpIdentityContextBuilder; String authority = "abc";
GrpcIdentityContextBuilder grpcIdentityContextBuilder; String username = "aa";
@Before String password = "12345";
public void setUp() {
httpIdentityContextBuilder = new HttpIdentityContextBuilder(); String key = "abc";
grpcIdentityContextBuilder = new GrpcIdentityContextBuilder();
@Test
public void testGrpcBuilt() {
//before
AuthConfigs authConfigs = Mockito.mock(AuthConfigs.class);
Mockito.when(authConfigs.getAuthorityKey()).thenReturn(new String[] {"authority", "username", "password"});
Request request = new HealthCheckRequest();
request.putHeader("authority", authority);
request.putHeader("username", username);
request.putHeader("password", password);
request.putHeader("key", key);
//when
GrpcIdentityContextBuilder grpcIdentityContextBuilder = new GrpcIdentityContextBuilder(authConfigs);
IdentityContext identityContext = grpcIdentityContextBuilder.build(request);
//then
Assert.assertEquals(authority, identityContext.getParameter("authority"));
Assert.assertEquals(username, identityContext.getParameter("username"));
Assert.assertEquals(password, identityContext.getParameter("password"));
Assert.assertNotEquals(key, identityContext.getParameter("key"));
} }
@Test @Test
public void testBuilt() throws AuthConfigsException { public void testHttpHeaderBuilt() {
HttpServletRequest httpRequest = new MockHttpServletRequest(); //before
Request grpcRequest = new ConnectionSetupRequest(); AuthConfigs authConfigs = Mockito.mock(AuthConfigs.class);
Assert.assertNotNull(httpIdentityContextBuilder.build(httpRequest)); Mockito.when(authConfigs.getAuthorityKey()).thenReturn(new String[] {"authority", "username", "password"});
Assert.assertNotNull(grpcIdentityContextBuilder.build(grpcRequest));
Vector<String> vector = new Vector<>();
vector.add("username");
vector.add("authority");
vector.add("password");
vector.add("key");
Enumeration<String> enumeration = vector.elements();
HttpServletRequest httpRequest = Mockito.mock(HttpServletRequest.class);
Mockito.when(httpRequest.getHeaderNames()).thenReturn(enumeration);
Mockito.when(httpRequest.getHeader("username")).thenReturn(username);
Mockito.when(httpRequest.getHeader("password")).thenReturn(password);
Mockito.when(httpRequest.getHeader("authority")).thenReturn(authority);
Mockito.when(httpRequest.getHeader("key")).thenReturn(key);
//when
HttpIdentityContextBuilder httpIdentityContextBuilder = new HttpIdentityContextBuilder(authConfigs);
IdentityContext identityContext = httpIdentityContextBuilder.build(httpRequest);
//then
Assert.assertEquals(authority, identityContext.getParameter("authority"));
Assert.assertEquals(username, identityContext.getParameter("username"));
Assert.assertEquals(password, identityContext.getParameter("password"));
Assert.assertNotEquals(key, identityContext.getParameter("key"));
}
@Test
public void testHttpParamBuilt() {
//before
AuthConfigs authConfigs = Mockito.mock(AuthConfigs.class);
Mockito.when(authConfigs.getAuthorityKey()).thenReturn(new String[] {"authority", "username", "password"});
Vector<String> vectorHeader = new Vector<>();
vectorHeader.add("URL");
Enumeration<String> enumerationHeader = vectorHeader.elements();
HttpServletRequest httpRequest = Mockito.mock(HttpServletRequest.class);
Mockito.when(httpRequest.getHeaderNames()).thenReturn(enumerationHeader);
Vector<String> vectorParam = new Vector<>();
vectorParam.add("username");
vectorParam.add("authority");
vectorParam.add("password");
Enumeration<String> enumerationParam = vectorParam.elements();
Mockito.when(httpRequest.getParameterNames()).thenReturn(enumerationParam);
Mockito.when(httpRequest.getHeader("URL")).thenReturn("localhost");
Mockito.when(httpRequest.getParameter("username")).thenReturn(username);
Mockito.when(httpRequest.getParameter("password")).thenReturn(password);
Mockito.when(httpRequest.getParameter("authority")).thenReturn(authority);
Mockito.when(httpRequest.getParameter("key")).thenReturn(key);
//when
HttpIdentityContextBuilder httpIdentityContextBuilder = new HttpIdentityContextBuilder(authConfigs);
IdentityContext identityContext = httpIdentityContextBuilder.build(httpRequest);
//then
Assert.assertEquals(authority, identityContext.getParameter("authority"));
Assert.assertEquals(username, identityContext.getParameter("username"));
Assert.assertEquals(password, identityContext.getParameter("password"));
Assert.assertNotEquals(key, identityContext.getParameter("key"));
}
@Test
public void testHttpHeaderParamBuilt() {
//before
AuthConfigs authConfigs = Mockito.mock(AuthConfigs.class);
Mockito.when(authConfigs.getAuthorityKey()).thenReturn(new String[] {"authority", "username", "password"});
Vector<String> vectorHeader = new Vector<>();
vectorHeader.add("URL");
vectorHeader.add("username");
vectorHeader.add("password");
Enumeration<String> enumerationHeader = vectorHeader.elements();
HttpServletRequest httpRequest = Mockito.mock(HttpServletRequest.class);
Mockito.when(httpRequest.getHeaderNames()).thenReturn(enumerationHeader);
Mockito.when(httpRequest.getHeader("URL")).thenReturn("localhost");
Mockito.when(httpRequest.getHeader("username")).thenReturn(username);
Mockito.when(httpRequest.getHeader("password")).thenReturn("54321");
Vector<String> vectorParam = new Vector<>();
vectorParam.add("username");
vectorParam.add("authority");
vectorParam.add("password");
Enumeration<String> enumerationParam = vectorParam.elements();
Mockito.when(httpRequest.getParameterNames()).thenReturn(enumerationParam);
Mockito.when(httpRequest.getParameter("password")).thenReturn(password);
Mockito.when(httpRequest.getParameter("authority")).thenReturn(authority);
Mockito.when(httpRequest.getParameter("key")).thenReturn(key);
//when
HttpIdentityContextBuilder httpIdentityContextBuilder = new HttpIdentityContextBuilder(authConfigs);
IdentityContext identityContext = httpIdentityContextBuilder.build(httpRequest);
//then
Assert.assertEquals(authority, identityContext.getParameter("authority"));
Assert.assertEquals(username, identityContext.getParameter("username"));
Assert.assertNotEquals(password, identityContext.getParameter("password"));
Assert.assertNotEquals(key, identityContext.getParameter("key"));
} }
} }

View File

@ -141,9 +141,6 @@ nacos.core.auth.enable.userAgentAuthWhite=false
nacos.core.auth.server.identity.key=serverIdentity nacos.core.auth.server.identity.key=serverIdentity
nacos.core.auth.server.identity.value=security nacos.core.auth.server.identity.value=security
### The default identify Position:
nacos.core.auth.identifyPosition=HEADER
### authority key in request: ### authority key in request:
nacos.core.auth.authorityKey=authority,username,password nacos.core.auth.authorityKey=authority,username,password

View File

@ -146,9 +146,6 @@ nacos.core.auth.system.type=nacos
### If turn on auth system: ### If turn on auth system:
nacos.core.auth.enabled=false nacos.core.auth.enabled=false
### The default identify Position:
nacos.core.auth.identifyPosition=HEADER
### authority key in request: ### authority key in request:
nacos.core.auth.authorityKey=authority,username,password nacos.core.auth.authorityKey=authority,username,password