[ISSUE#5696] IdentityContext build from resource and remote ip. (#7745)
* validateIdentity add Resource input for extension. * IdentityContext parse remoteIp.
This commit is contained in:
parent
080f1ff592
commit
64dcc0ed0a
@ -46,14 +46,14 @@ public abstract class AbstractProtocolAuthService<R> implements ProtocolAuthServ
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateIdentity(IdentityContext identityContext) throws AccessException {
|
||||
public boolean validateIdentity(IdentityContext identityContext, Resource resource) throws AccessException {
|
||||
if (!authConfigs.isAuthEnabled()) {
|
||||
return true;
|
||||
}
|
||||
Optional<AuthPluginService> authPluginService = AuthPluginManager.getInstance()
|
||||
.findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType());
|
||||
if (authPluginService.isPresent()) {
|
||||
return authPluginService.get().validateIdentity(identityContext);
|
||||
return authPluginService.get().validateIdentity(identityContext, resource);
|
||||
}
|
||||
Loggers.AUTH.warn("Can't find auth plugin for type {}, please add plugin to classpath or set {} as false",
|
||||
authConfigs.getNacosAuthSystemType(), Constants.Auth.NACOS_CORE_AUTH_ENABLED);
|
||||
|
@ -55,16 +55,17 @@ public interface ProtocolAuthService<R> {
|
||||
* Validate identity whether is legal.
|
||||
*
|
||||
* @param identityContext identity context
|
||||
* @param resource resource
|
||||
* @return {@code true} if legal, otherwise {@code false}
|
||||
* @throws AccessException exception during validating
|
||||
*/
|
||||
boolean validateIdentity(IdentityContext identityContext) throws AccessException;
|
||||
boolean validateIdentity(IdentityContext identityContext, Resource resource) throws AccessException;
|
||||
|
||||
/**
|
||||
* Validate identity whether had permission for the resource and action.
|
||||
*
|
||||
* @param identityContext identity context
|
||||
* @param permission permssion include resource and action
|
||||
* @param permission permission include resource and action
|
||||
* @return {@code true} if legal, otherwise {@code false}
|
||||
* @throws AccessException exception during validating
|
||||
*/
|
||||
|
@ -17,10 +17,11 @@
|
||||
package com.alibaba.nacos.auth.context;
|
||||
|
||||
import com.alibaba.nacos.api.remote.request.Request;
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.plugin.auth.constant.Constants;
|
||||
import com.alibaba.nacos.plugin.auth.spi.server.AuthPluginManager;
|
||||
import com.alibaba.nacos.plugin.auth.spi.server.AuthPluginService;
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@ -52,6 +53,7 @@ public class GrpcIdentityContextBuilder implements IdentityContextBuilder<Reques
|
||||
Optional<AuthPluginService> authPluginService = AuthPluginManager.getInstance()
|
||||
.findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType());
|
||||
IdentityContext result = new IdentityContext();
|
||||
getRemoteIp(request, result);
|
||||
if (!authPluginService.isPresent()) {
|
||||
return result;
|
||||
}
|
||||
@ -64,4 +66,8 @@ public class GrpcIdentityContextBuilder implements IdentityContextBuilder<Reques
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getRemoteIp(Request request, IdentityContext result) {
|
||||
result.setParameter(Constants.Identity.REMOTE_IP, request.getHeader(Constants.Identity.X_REAL_IP));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.auth.context;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.auth.constant.Constants;
|
||||
import com.alibaba.nacos.plugin.auth.spi.server.AuthPluginManager;
|
||||
import com.alibaba.nacos.plugin.auth.spi.server.AuthPluginService;
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
@ -35,6 +37,10 @@ import java.util.Set;
|
||||
*/
|
||||
public class HttpIdentityContextBuilder implements IdentityContextBuilder<HttpServletRequest> {
|
||||
|
||||
private static final String X_FORWARDED_FOR = "X-Forwarded-For";
|
||||
|
||||
private static final String X_FORWARDED_FOR_SPLIT_SYMBOL = ",";
|
||||
|
||||
private final AuthConfigs authConfigs;
|
||||
|
||||
public HttpIdentityContextBuilder(AuthConfigs authConfigs) {
|
||||
@ -50,6 +56,7 @@ public class HttpIdentityContextBuilder implements IdentityContextBuilder<HttpSe
|
||||
@Override
|
||||
public IdentityContext build(HttpServletRequest request) {
|
||||
IdentityContext result = new IdentityContext();
|
||||
getRemoteIp(request, result);
|
||||
Optional<AuthPluginService> authPluginService = AuthPluginManager.getInstance()
|
||||
.findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType());
|
||||
if (!authPluginService.isPresent()) {
|
||||
@ -80,4 +87,17 @@ public class HttpIdentityContextBuilder implements IdentityContextBuilder<HttpSe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getRemoteIp(HttpServletRequest request, IdentityContext result) {
|
||||
String remoteIp = StringUtils.EMPTY;
|
||||
String xForwardedFor = request.getHeader(X_FORWARDED_FOR);
|
||||
if (!StringUtils.isBlank(xForwardedFor)) {
|
||||
remoteIp = xForwardedFor.split(X_FORWARDED_FOR_SPLIT_SYMBOL)[0].trim();
|
||||
}
|
||||
if (StringUtils.isBlank(remoteIp)) {
|
||||
String nginxHeader = request.getHeader(Constants.Identity.X_REAL_IP);
|
||||
remoteIp = StringUtils.isBlank(nginxHeader) ? request.getRemoteAddr() : nginxHeader;
|
||||
}
|
||||
result.setParameter(Constants.Identity.REMOTE_IP, remoteIp);
|
||||
}
|
||||
}
|
||||
|
@ -130,14 +130,14 @@ public class GrpcProtocolAuthServiceTest {
|
||||
@Test
|
||||
public void testValidateIdentityWithoutPlugin() throws AccessException {
|
||||
IdentityContext identityContext = new IdentityContext();
|
||||
assertTrue(protocolAuthService.validateIdentity(identityContext));
|
||||
assertTrue(protocolAuthService.validateIdentity(identityContext, Resource.EMPTY_RESOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateIdentityWithPlugin() throws AccessException {
|
||||
Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
|
||||
IdentityContext identityContext = new IdentityContext();
|
||||
assertFalse(protocolAuthService.validateIdentity(identityContext));
|
||||
assertFalse(protocolAuthService.validateIdentity(identityContext, Resource.EMPTY_RESOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -120,14 +120,14 @@ public class HttpProtocolAuthServiceTest {
|
||||
@Test
|
||||
public void testValidateIdentityWithoutPlugin() throws AccessException {
|
||||
IdentityContext identityContext = new IdentityContext();
|
||||
assertTrue(httpProtocolAuthService.validateIdentity(identityContext));
|
||||
assertTrue(httpProtocolAuthService.validateIdentity(identityContext, Resource.EMPTY_RESOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateIdentityWithPlugin() throws AccessException {
|
||||
Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
|
||||
IdentityContext identityContext = new IdentityContext();
|
||||
assertFalse(httpProtocolAuthService.validateIdentity(identityContext));
|
||||
assertFalse(httpProtocolAuthService.validateIdentity(identityContext, Resource.EMPTY_RESOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -19,6 +19,7 @@ package com.alibaba.nacos.auth.context;
|
||||
import com.alibaba.nacos.api.remote.request.Request;
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.plugin.auth.constant.Constants;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -56,6 +57,7 @@ public class GrpcIdentityContextBuilderTest {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put(IDENTITY_TEST_KEY, IDENTITY_TEST_VALUE);
|
||||
when(request.getHeaders()).thenReturn(headers);
|
||||
when(request.getHeader(Constants.Identity.X_REAL_IP)).thenReturn("1.1.1.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -69,5 +71,6 @@ public class GrpcIdentityContextBuilderTest {
|
||||
public void testBuild() {
|
||||
IdentityContext actual = identityContextBuilder.build(request);
|
||||
assertEquals(IDENTITY_TEST_VALUE, actual.getParameter(IDENTITY_TEST_KEY));
|
||||
assertEquals("1.1.1.1", actual.getParameter(Constants.Identity.REMOTE_IP));
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.auth.context;
|
||||
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.plugin.auth.constant.Constants;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -75,6 +76,7 @@ public class HtppIdentityContextBuilderTest {
|
||||
mockParameter(false);
|
||||
IdentityContext actual = identityContextBuilder.build(request);
|
||||
assertEquals(IDENTITY_TEST_VALUE, actual.getParameter(IDENTITY_TEST_KEY));
|
||||
assertEquals("1.1.1.1", actual.getParameter(Constants.Identity.REMOTE_IP));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -91,6 +93,7 @@ public class HtppIdentityContextBuilderTest {
|
||||
when(headerNames.hasMoreElements()).thenReturn(true, false);
|
||||
when(headerNames.nextElement()).thenReturn(IDENTITY_TEST_KEY, (String) null);
|
||||
when(request.getHeader(IDENTITY_TEST_KEY)).thenReturn(IDENTITY_TEST_VALUE);
|
||||
when(request.getHeader(Constants.Identity.X_REAL_IP)).thenReturn("1.1.1.1");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.auth.mock;
|
||||
|
||||
import com.alibaba.nacos.plugin.auth.api.Resource;
|
||||
import com.alibaba.nacos.plugin.auth.spi.server.AuthPluginService;
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.plugin.auth.api.Permission;
|
||||
@ -36,7 +37,7 @@ public class MockAuthPluginService implements AuthPluginService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateIdentity(IdentityContext identityContext) throws AccessException {
|
||||
public boolean validateIdentity(IdentityContext identityContext, Resource resource) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ public class AuthFilter implements Filter {
|
||||
Secured secured = method.getAnnotation(Secured.class);
|
||||
Resource resource = protocolAuthService.parseResource(req, secured);
|
||||
IdentityContext identityContext = protocolAuthService.parseIdentity(req);
|
||||
boolean result = protocolAuthService.validateIdentity(identityContext);
|
||||
boolean result = protocolAuthService.validateIdentity(identityContext, resource);
|
||||
if (!result) {
|
||||
// TODO Get reason of failure
|
||||
throw new AccessException("Validate Identity failed.");
|
||||
|
@ -29,6 +29,7 @@ import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.plugin.auth.api.Permission;
|
||||
import com.alibaba.nacos.plugin.auth.api.Resource;
|
||||
import com.alibaba.nacos.plugin.auth.constant.Constants;
|
||||
import com.alibaba.nacos.plugin.auth.exception.AccessException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -66,9 +67,11 @@ public class RemoteRequestAuthFilter extends AbstractRequestFilter {
|
||||
}
|
||||
|
||||
Secured secured = method.getAnnotation(Secured.class);
|
||||
String clientIp = meta.getClientIp();
|
||||
request.putHeader(Constants.Identity.X_REAL_IP, clientIp);
|
||||
Resource resource = protocolAuthService.parseResource(request, secured);
|
||||
IdentityContext identityContext = protocolAuthService.parseIdentity(request);
|
||||
boolean result = protocolAuthService.validateIdentity(identityContext);
|
||||
boolean result = protocolAuthService.validateIdentity(identityContext, resource);
|
||||
if (!result) {
|
||||
// TODO Get reason of failure
|
||||
throw new AccessException("Validate Identity failed.");
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.alibaba.nacos.plugin.auth.impl;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.plugin.auth.api.Resource;
|
||||
import com.alibaba.nacos.plugin.auth.impl.users.User;
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.plugin.auth.api.Permission;
|
||||
@ -57,7 +58,7 @@ public class NacosAuthPluginService implements AuthPluginService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateIdentity(IdentityContext identityContext) throws AccessException {
|
||||
public boolean validateIdentity(IdentityContext identityContext, Resource resource) throws AccessException {
|
||||
checkNacosAuthManager();
|
||||
User user = nacosAuthManager.login(identityContext);
|
||||
identityContext.setParameter(USER_IDENTITY_PARAM_KEY, user);
|
||||
|
@ -48,5 +48,9 @@ public class Constants {
|
||||
public static class Identity {
|
||||
|
||||
public static final String IDENTITY_ID = "identity_id";
|
||||
|
||||
public static final String X_REAL_IP = "X-Real-IP";
|
||||
|
||||
public static final String REMOTE_IP = "remote_ip";
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.plugin.auth.spi.server;
|
||||
|
||||
import com.alibaba.nacos.plugin.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.plugin.auth.api.Permission;
|
||||
import com.alibaba.nacos.plugin.auth.api.Resource;
|
||||
import com.alibaba.nacos.plugin.auth.exception.AccessException;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -40,10 +41,11 @@ public interface AuthPluginService {
|
||||
* To validate whether the identity context from request is legal or illegal.
|
||||
*
|
||||
* @param identityContext where we can find the user information
|
||||
* @param resource resource about this user information
|
||||
* @return {@code true} if legal, otherwise {@code false}
|
||||
* @throws AccessException if authentication is failed
|
||||
*/
|
||||
boolean validateIdentity(IdentityContext identityContext) throws AccessException;
|
||||
boolean validateIdentity(IdentityContext identityContext, Resource resource) throws AccessException;
|
||||
|
||||
/**
|
||||
* Validate the identity whether has the resource authority.
|
||||
|
Loading…
Reference in New Issue
Block a user