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.
*
* @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
*/
Boolean login(IdentityContext identityContext) throws AccessException;
IdentityContext login(IdentityContext identityContext) throws AccessException;
/**
* identity whether the user has the resource authority.

View File

@ -46,12 +46,6 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
@JustForTest
private static Boolean cachingEnabled = null;
/**
* identifyContext position.
*/
@Value("${nacos.core.auth.identifyPosition:}")
private IdentifyPositionTypes identifyPosition;
/**
* Authority key set.
*/
@ -107,10 +101,6 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
return secretKeyBytes;
}
public IdentifyPositionTypes getIdentifyPositionTypes() {
return identifyPosition;
}
public String[] getAuthorityKey() {
return authorityKey;
}
@ -169,7 +159,6 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
serverIdentityKey = EnvUtil.getProperty("nacos.core.auth.server.identity.key", "");
serverIdentityValue = EnvUtil.getProperty("nacos.core.auth.server.identity.value", "");
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(",");
} catch (Exception 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;
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.
* @param request grpc request

View File

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

View File

@ -16,8 +16,6 @@
package com.alibaba.nacos.auth.context;
import com.alibaba.nacos.auth.exception.AuthConfigsException;
/**
* Identify context.
*
@ -29,8 +27,7 @@ public interface IdentityContextBuilder<T> {
* build identity context from request.
* @param request user request
* @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 IdentifyPositionTypes IDENTIFYPOSITION = IdentifyPositionTypes.HEADER_AND_PARAMETER;
private static final String AUTHORITYKEY = "username,password,token,tenant";
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.value", TEST_SERVER_IDENTITY_VALUE);
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);
authConfigs.onEvent(ServerConfigChangeEvent.newEvent());
@ -70,7 +67,6 @@ public class AuthConfigsTest {
assertEquals(TEST_SERVER_IDENTITY_KEY, authConfigs.getServerIdentityKey());
assertEquals(TEST_SERVER_IDENTITY_VALUE, authConfigs.getServerIdentityValue());
assertEquals(TEST_ENABLE_UA_WHITE, authConfigs.isEnableUserAgentAuthWhite());
assertEquals(IDENTIFYPOSITION.toString(), authConfigs.getIdentifyPositionTypes().toString());
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.AuthService;
import com.alibaba.nacos.auth.context.IdentityContext;
import com.alibaba.nacos.auth.exception.AccessException;
import com.alibaba.nacos.auth.model.Permission;
import org.junit.Assert;
import org.junit.Before;
@ -73,8 +72,7 @@ public class AuthPluginManagerTest {
}
@Test
public void testFindAuthServiceSpiImpl() throws AccessException {
Mockito.when(authService.login(identityContext)).thenReturn(true);
public void testFindAuthServiceSpiImpl() {
Mockito.when(authService.authorityAccess(identityContext, permission)).thenReturn(true);
Mockito.when(authService.getAuthServiceName()).thenReturn(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;
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.HttpIdentityContextBuilder;
import com.alibaba.nacos.auth.exception.AuthConfigsException;
import com.alibaba.nacos.auth.context.IdentityContext;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.alibaba.nacos.api.remote.request.Request;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Vector;
@RunWith(MockitoJUnitRunner.class)
public class IdentityContextBuilderTest {
HttpIdentityContextBuilder httpIdentityContextBuilder;
GrpcIdentityContextBuilder grpcIdentityContextBuilder;
String authority = "abc";
@Before
public void setUp() {
httpIdentityContextBuilder = new HttpIdentityContextBuilder();
grpcIdentityContextBuilder = new GrpcIdentityContextBuilder();
String username = "aa";
String password = "12345";
String key = "abc";
@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
public void testBuilt() throws AuthConfigsException {
HttpServletRequest httpRequest = new MockHttpServletRequest();
Request grpcRequest = new ConnectionSetupRequest();
Assert.assertNotNull(httpIdentityContextBuilder.build(httpRequest));
Assert.assertNotNull(grpcIdentityContextBuilder.build(grpcRequest));
public void testHttpHeaderBuilt() {
//before
AuthConfigs authConfigs = Mockito.mock(AuthConfigs.class);
Mockito.when(authConfigs.getAuthorityKey()).thenReturn(new String[] {"authority", "username", "password"});
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.value=security
### The default identify Position:
nacos.core.auth.identifyPosition=HEADER
### authority key in request:
nacos.core.auth.authorityKey=authority,username,password

View File

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