mirror of https://github.com/grpc/grpc-java.git
xds: implement RBAC gRFC misc cases (#8518)
This commit is contained in:
parent
fcf13952bb
commit
38a554c23a
|
|
@ -136,6 +136,10 @@ final class ClientXdsClient extends AbstractXdsClient {
|
|||
static boolean enableRetry =
|
||||
Strings.isNullOrEmpty(System.getenv("GRPC_XDS_EXPERIMENTAL_ENABLE_RETRY"))
|
||||
|| Boolean.parseBoolean(System.getenv("GRPC_XDS_EXPERIMENTAL_ENABLE_RETRY"));
|
||||
@VisibleForTesting
|
||||
static boolean enableRbac =
|
||||
Strings.isNullOrEmpty(System.getenv("GRPC_XDS_EXPERIMENTAL_RBAC"))
|
||||
|| Boolean.parseBoolean(System.getenv("GRPC_XDS_EXPERIMENTAL_RBAC"));
|
||||
|
||||
private static final String TYPE_URL_HTTP_CONNECTION_MANAGER_V2 =
|
||||
"type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2"
|
||||
|
|
@ -218,7 +222,7 @@ final class ClientXdsClient extends AbstractXdsClient {
|
|||
listener, retainedRdsResources, enableFaultInjection && isResourceV3);
|
||||
} else {
|
||||
ldsUpdate = processServerSideListener(
|
||||
listener, retainedRdsResources, enableFaultInjection && isResourceV3);
|
||||
listener, retainedRdsResources, enableRbac);
|
||||
}
|
||||
} catch (ResourceInvalidException e) {
|
||||
errors.add(
|
||||
|
|
@ -729,10 +733,14 @@ final class ClientXdsClient extends AbstractXdsClient {
|
|||
static io.grpc.xds.HttpConnectionManager parseHttpConnectionManager(
|
||||
HttpConnectionManager proto, Set<String> rdsResources, FilterRegistry filterRegistry,
|
||||
boolean parseHttpFilter, boolean isForClient) throws ResourceInvalidException {
|
||||
if (proto.getXffNumTrustedHops() != 0) {
|
||||
if (enableRbac && proto.getXffNumTrustedHops() != 0) {
|
||||
throw new ResourceInvalidException(
|
||||
"HttpConnectionManager with xff_num_trusted_hops unsupported");
|
||||
}
|
||||
if (enableRbac && !proto.getOriginalIpDetectionExtensionsList().isEmpty()) {
|
||||
throw new ResourceInvalidException("HttpConnectionManager with "
|
||||
+ "original_ip_detection_extensions unsupported");
|
||||
}
|
||||
// Obtain max_stream_duration from Http Protocol Options.
|
||||
long maxStreamDuration = 0;
|
||||
if (proto.hasCommonHttpProtocolOptions()) {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import io.envoyproxy.envoy.config.rbac.v3.Policy;
|
|||
import io.envoyproxy.envoy.config.rbac.v3.Principal;
|
||||
import io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBAC;
|
||||
import io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBACPerRoute;
|
||||
import io.envoyproxy.envoy.type.v3.Int32Range;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.ServerCall;
|
||||
import io.grpc.ServerCallHandler;
|
||||
|
|
@ -45,6 +46,7 @@ import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.AuthHeaderMatche
|
|||
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.AuthenticatedMatcher;
|
||||
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.DestinationIpMatcher;
|
||||
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.DestinationPortMatcher;
|
||||
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.DestinationPortRangeMatcher;
|
||||
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.InvertMatcher;
|
||||
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.Matcher;
|
||||
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.OrMatcher;
|
||||
|
|
@ -216,6 +218,8 @@ final class RbacFilter implements Filter, ServerInterceptorBuilder {
|
|||
return createDestinationIpMatcher(permission.getDestinationIp());
|
||||
case DESTINATION_PORT:
|
||||
return createDestinationPortMatcher(permission.getDestinationPort());
|
||||
case DESTINATION_PORT_RANGE:
|
||||
return parseDestinationPortRangeMatcher(permission.getDestinationPortRange());
|
||||
case NOT_RULE:
|
||||
return new InvertMatcher(parsePermission(permission.getNotRule()));
|
||||
case METADATA: // hard coded, never match.
|
||||
|
|
@ -291,6 +295,14 @@ final class RbacFilter implements Filter, ServerInterceptorBuilder {
|
|||
|
||||
private static AuthHeaderMatcher parseHeaderMatcher(
|
||||
io.envoyproxy.envoy.config.route.v3.HeaderMatcher proto) {
|
||||
if (proto.getName().startsWith("grpc-")) {
|
||||
throw new IllegalArgumentException("Invalid header matcher config: [grpc-] prefixed "
|
||||
+ "header name is not allowed.");
|
||||
}
|
||||
if (":scheme".equals(proto.getName())) {
|
||||
throw new IllegalArgumentException("Invalid header matcher config: header name [:scheme] "
|
||||
+ "is not allowed.");
|
||||
}
|
||||
return new AuthHeaderMatcher(MatcherParser.parseHeaderMatcher(proto));
|
||||
}
|
||||
|
||||
|
|
@ -304,6 +316,10 @@ final class RbacFilter implements Filter, ServerInterceptorBuilder {
|
|||
return new DestinationPortMatcher(port);
|
||||
}
|
||||
|
||||
private static DestinationPortRangeMatcher parseDestinationPortRangeMatcher(Int32Range range) {
|
||||
return new DestinationPortRangeMatcher(range.getStart(), range.getEnd());
|
||||
}
|
||||
|
||||
private static DestinationIpMatcher createDestinationIpMatcher(CidrRange cidrRange) {
|
||||
return new DestinationIpMatcher(Matchers.CidrMatcher.create(
|
||||
resolve(cidrRange), cidrRange.getPrefixLen().getValue()));
|
||||
|
|
|
|||
|
|
@ -639,6 +639,9 @@ final class XdsServerWrapper extends Server {
|
|||
if (!routeDiscoveryStates.containsKey(resourceName)) {
|
||||
return;
|
||||
}
|
||||
if (savedVirtualHosts == null && !isPending) {
|
||||
logger.log(Level.WARNING, "Received valid Rds {0} configuration.", resourceName);
|
||||
}
|
||||
savedVirtualHosts = ImmutableList.copyOf(update.virtualHosts);
|
||||
updateRdsRoutingConfig();
|
||||
maybeUpdateSelector();
|
||||
|
|
@ -760,11 +763,15 @@ final class XdsServerWrapper extends Server {
|
|||
}
|
||||
}
|
||||
if (selectedRoute == null) {
|
||||
call.close(
|
||||
Status.UNAVAILABLE.withDescription("Could not find xDS route matching RPC"),
|
||||
call.close(Status.UNAVAILABLE.withDescription("Could not find xDS route matching RPC"),
|
||||
new Metadata());
|
||||
return new ServerCall.Listener<ReqT>() {};
|
||||
}
|
||||
if (selectedRoute.routeAction() != null) {
|
||||
call.close(Status.UNAVAILABLE.withDescription("Invalid xDS route action for matching "
|
||||
+ "route: only Route.non_forwarding_action should be allowed."), new Metadata());
|
||||
return new ServerCall.Listener<ReqT>() {};
|
||||
}
|
||||
ServerInterceptor routeInterceptor = noopInterceptor;
|
||||
Map<Route, ServerInterceptor> perRouteInterceptors = routingConfig.interceptors();
|
||||
if (perRouteInterceptors != null && perRouteInterceptors.get(selectedRoute) != null) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import io.grpc.Grpc;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.ServerCall;
|
||||
|
|
@ -35,6 +36,7 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -234,6 +236,23 @@ public final class GrpcAuthorizationEngine {
|
|||
}
|
||||
}
|
||||
|
||||
public static final class DestinationPortRangeMatcher implements Matcher {
|
||||
private final int start;
|
||||
private final int end;
|
||||
|
||||
/** Start of the range is inclusive. End of the range is exclusive.*/
|
||||
public DestinationPortRangeMatcher(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(EvaluateArgs args) {
|
||||
int port = args.getDestinationPort();
|
||||
return port >= start && port < end;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class RequestedServerNameMatcher implements Matcher {
|
||||
private final Matchers.StringMatcher delegate;
|
||||
|
||||
|
|
@ -316,9 +335,44 @@ public final class GrpcAuthorizationEngine {
|
|||
|
||||
@Nullable
|
||||
private String getHeader(String headerName) {
|
||||
if (headerName.endsWith(Metadata.BINARY_HEADER_SUFFIX)) {
|
||||
headerName = headerName.toLowerCase(Locale.ROOT);
|
||||
if ("te".equals(headerName)) {
|
||||
return null;
|
||||
}
|
||||
if (":authority".equals(headerName)) {
|
||||
headerName = "host";
|
||||
}
|
||||
if ("host".equals(headerName)) {
|
||||
return serverCall.getAuthority();
|
||||
}
|
||||
if (":path".equals(headerName)) {
|
||||
return getPath();
|
||||
}
|
||||
if (":method".equals(headerName)) {
|
||||
return "POST";
|
||||
}
|
||||
return deserializeHeader(headerName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String deserializeHeader(String headerName) {
|
||||
if (headerName.endsWith(Metadata.BINARY_HEADER_SUFFIX)) {
|
||||
Metadata.Key<byte[]> key;
|
||||
try {
|
||||
key = Metadata.Key.of(headerName, Metadata.BINARY_BYTE_MARSHALLER);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
Iterable<byte[]> values = metadata.getAll(key);
|
||||
if (values == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> encoded = new ArrayList<>();
|
||||
for (byte[] v : values) {
|
||||
encoded.add(BaseEncoding.base64().omitPadding().encode(v));
|
||||
}
|
||||
return Joiner.on(",").join(encoded);
|
||||
}
|
||||
Metadata.Key<String> key;
|
||||
try {
|
||||
key = Metadata.Key.of(headerName, Metadata.ASCII_STRING_MARSHALLER);
|
||||
|
|
|
|||
|
|
@ -131,16 +131,20 @@ public class ClientXdsClientDataTest {
|
|||
public final ExpectedException thrown = ExpectedException.none();
|
||||
private final FilterRegistry filterRegistry = FilterRegistry.getDefaultRegistry();
|
||||
private boolean originalEnableRetry;
|
||||
private boolean originalEnableRbac;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
originalEnableRetry = ClientXdsClient.enableRetry;
|
||||
assertThat(originalEnableRetry).isTrue();
|
||||
originalEnableRbac = ClientXdsClient.enableRbac;
|
||||
assertThat(originalEnableRbac).isTrue();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ClientXdsClient.enableRetry = originalEnableRetry;
|
||||
ClientXdsClient.enableRbac = originalEnableRbac;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1109,6 +1113,19 @@ public class ClientXdsClientDataTest {
|
|||
true /* does not matter */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseHttpConnectionManager_OriginalIpDetectionExtensionsMustEmpty()
|
||||
throws ResourceInvalidException {
|
||||
@SuppressWarnings("deprecation")
|
||||
HttpConnectionManager hcm = HttpConnectionManager.newBuilder()
|
||||
.addOriginalIpDetectionExtensions(TypedExtensionConfig.newBuilder().build())
|
||||
.build();
|
||||
thrown.expect(ResourceInvalidException.class);
|
||||
thrown.expectMessage("HttpConnectionManager with original_ip_detection_extensions unsupported");
|
||||
ClientXdsClient.parseHttpConnectionManager(
|
||||
hcm, new HashSet<String>(), filterRegistry, false /* does not matter */, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseHttpConnectionManager_missingRdsAndInlinedRouteConfiguration()
|
||||
throws ResourceInvalidException {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBACPerRoute;
|
|||
import io.envoyproxy.envoy.type.matcher.v3.MetadataMatcher;
|
||||
import io.envoyproxy.envoy.type.matcher.v3.PathMatcher;
|
||||
import io.envoyproxy.envoy.type.matcher.v3.StringMatcher;
|
||||
import io.envoyproxy.envoy.type.v3.Int32Range;
|
||||
import io.grpc.Attributes;
|
||||
import io.grpc.Grpc;
|
||||
import io.grpc.Metadata;
|
||||
|
|
@ -109,6 +110,33 @@ public class RbacFilterTest {
|
|||
assertThat(decision.decision()).isEqualTo(GrpcAuthorizationEngine.Action.DENY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"unchecked", "deprecation"})
|
||||
public void portRangeParser() {
|
||||
List<Permission> permissionList = Arrays.asList(
|
||||
Permission.newBuilder().setDestinationPortRange(
|
||||
Int32Range.newBuilder().setStart(1010).setEnd(65535).build()
|
||||
).build());
|
||||
List<Principal> principalList = Arrays.asList(
|
||||
Principal.newBuilder().setRemoteIp(
|
||||
CidrRange.newBuilder().setAddressPrefix("10.10.10.0")
|
||||
.setPrefixLen(UInt32Value.of(24)).build()
|
||||
).build());
|
||||
ConfigOrError<?> result = parse(permissionList, principalList);
|
||||
assertThat(result.errorDetail).isNull();
|
||||
ServerCall<Void,Void> serverCall = mock(ServerCall.class);
|
||||
Attributes attributes = Attributes.newBuilder()
|
||||
.set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, new InetSocketAddress("10.10.10.0", 1))
|
||||
.set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, new InetSocketAddress("10.10.10.0",9090))
|
||||
.build();
|
||||
when(serverCall.getAttributes()).thenReturn(attributes);
|
||||
when(serverCall.getMethodDescriptor()).thenReturn(method().build());
|
||||
GrpcAuthorizationEngine engine =
|
||||
new GrpcAuthorizationEngine(((RbacConfig)result.config).authConfig());
|
||||
AuthDecision decision = engine.evaluate(new Metadata(), serverCall);
|
||||
assertThat(decision.decision()).isEqualTo(GrpcAuthorizationEngine.Action.DENY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void pathParser() {
|
||||
|
|
@ -172,6 +200,21 @@ public class RbacFilterTest {
|
|||
assertThat(decision.decision()).isEqualTo(GrpcAuthorizationEngine.Action.DENY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void headerParser_headerName() {
|
||||
HeaderMatcher headerMatcher = HeaderMatcher.newBuilder()
|
||||
.setName("grpc--feature").setExactMatch("win").build();
|
||||
List<Permission> permissionList = Arrays.asList(
|
||||
Permission.newBuilder().setHeader(headerMatcher).build());
|
||||
HeaderMatcher headerMatcher2 = HeaderMatcher.newBuilder()
|
||||
.setName(":scheme").setExactMatch("win").build();
|
||||
List<Principal> principalList = Arrays.asList(
|
||||
Principal.newBuilder().setHeader(headerMatcher2).build());
|
||||
ConfigOrError<RbacConfig> result = parseOverride(permissionList, principalList);
|
||||
assertThat(result.errorDetail).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void compositeRules() {
|
||||
|
|
|
|||
|
|
@ -865,6 +865,50 @@ public class XdsServerWrapperTest {
|
|||
assertThat(status.getDescription()).isEqualTo("Could not find xDS route matching RPC");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void interceptor_invalidRouteAction() throws Exception {
|
||||
ArgumentCaptor<ConfigApplyingInterceptor> interceptorCaptor =
|
||||
ArgumentCaptor.forClass(ConfigApplyingInterceptor.class);
|
||||
final SettableFuture<Server> start = SettableFuture.create();
|
||||
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
start.set(xdsServerWrapper.start());
|
||||
} catch (Exception ex) {
|
||||
start.setException(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
|
||||
verify(mockBuilder).intercept(interceptorCaptor.capture());
|
||||
ConfigApplyingInterceptor interceptor = interceptorCaptor.getValue();
|
||||
ServerRoutingConfig routingConfig = createRoutingConfig("/FooService/barMethod",
|
||||
"foo.google.com", "filter-type-url", Route.RouteAction.forCluster(
|
||||
"cluster", Collections.<Route.RouteAction.HashPolicy>emptyList(), null, null
|
||||
));
|
||||
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
||||
when(serverCall.getAttributes()).thenReturn(
|
||||
Attributes.newBuilder()
|
||||
.set(ATTR_SERVER_ROUTING_CONFIG, new AtomicReference<>(routingConfig)).build());
|
||||
when(serverCall.getMethodDescriptor()).thenReturn(createMethod("FooService/barMethod"));
|
||||
when(serverCall.getAuthority()).thenReturn("foo.google.com");
|
||||
|
||||
Filter filter = mock(Filter.class);
|
||||
when(filter.typeUrls()).thenReturn(new String[]{"filter-type-url"});
|
||||
filterRegistry.register(filter);
|
||||
ServerCallHandler<Void, Void> next = mock(ServerCallHandler.class);
|
||||
interceptor.interceptCall(serverCall, new Metadata(), next);
|
||||
verify(next, never()).startCall(any(ServerCall.class), any(Metadata.class));
|
||||
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
|
||||
verify(serverCall).close(statusCaptor.capture(), any(Metadata.class));
|
||||
Status status = statusCaptor.getValue();
|
||||
assertThat(status.getCode()).isEqualTo(Status.UNAVAILABLE.getCode());
|
||||
assertThat(status.getDescription()).isEqualTo("Invalid xDS route action for matching "
|
||||
+ "route: only Route.non_forwarding_action should be allowed.");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void interceptor_failingRouterConfig() throws Exception {
|
||||
|
|
@ -1104,13 +1148,18 @@ public class XdsServerWrapperTest {
|
|||
|
||||
private static ServerRoutingConfig createRoutingConfig(String path, String domain,
|
||||
String filterType) {
|
||||
return createRoutingConfig(path, domain, filterType, null);
|
||||
}
|
||||
|
||||
private static ServerRoutingConfig createRoutingConfig(String path, String domain,
|
||||
String filterType, Route.RouteAction action) {
|
||||
RouteMatch routeMatch =
|
||||
RouteMatch.create(
|
||||
PathMatcher.fromPath(path, true),
|
||||
Collections.<HeaderMatcher>emptyList(), null);
|
||||
VirtualHost virtualHost = VirtualHost.create(
|
||||
"v1", Collections.singletonList(domain),
|
||||
Arrays.asList(Route.forAction(routeMatch, null,
|
||||
Arrays.asList(Route.forAction(routeMatch, action,
|
||||
ImmutableMap.<String, FilterConfig>of())),
|
||||
Collections.<String, FilterConfig>emptyMap());
|
||||
FilterConfig f0 = mock(FilterConfig.class);
|
||||
|
|
|
|||
|
|
@ -16,12 +16,14 @@
|
|||
|
||||
package io.grpc.xds.internal.rbac.engine;
|
||||
|
||||
import static com.google.common.base.Charsets.US_ASCII;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import io.grpc.Attributes;
|
||||
import io.grpc.Grpc;
|
||||
import io.grpc.Metadata;
|
||||
|
|
@ -177,6 +179,71 @@ public class GrpcAuthorizationEngineTest {
|
|||
assertThat(decision.decision()).isEqualTo(Action.DENY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerMatcher_binaryHeader() {
|
||||
AuthHeaderMatcher headerMatcher = new AuthHeaderMatcher(Matchers.HeaderMatcher
|
||||
.forExactValue(HEADER_KEY + Metadata.BINARY_HEADER_SUFFIX,
|
||||
BaseEncoding.base64().omitPadding().encode(HEADER_VALUE.getBytes(US_ASCII)), false));
|
||||
OrMatcher principal = OrMatcher.create(headerMatcher);
|
||||
OrMatcher permission = OrMatcher.create(
|
||||
new InvertMatcher(new DestinationPortMatcher(PORT + 1)));
|
||||
PolicyMatcher policyMatcher = new PolicyMatcher(POLICY_NAME, permission, principal);
|
||||
GrpcAuthorizationEngine engine = new GrpcAuthorizationEngine(
|
||||
new AuthConfig(Collections.singletonList(policyMatcher), Action.ALLOW));
|
||||
Metadata metadata = new Metadata();
|
||||
metadata.put(Metadata.Key.of(HEADER_KEY + Metadata.BINARY_HEADER_SUFFIX,
|
||||
Metadata.BINARY_BYTE_MARSHALLER), HEADER_VALUE.getBytes(US_ASCII));
|
||||
AuthDecision decision = engine.evaluate(metadata, serverCall);
|
||||
assertThat(decision.decision()).isEqualTo(Action.ALLOW);
|
||||
assertThat(decision.matchingPolicyName()).isEqualTo(POLICY_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerMatcher_hardcodePostMethod() {
|
||||
AuthHeaderMatcher headerMatcher = new AuthHeaderMatcher(Matchers.HeaderMatcher
|
||||
.forExactValue(":method", "POST", false));
|
||||
OrMatcher principal = OrMatcher.create(headerMatcher);
|
||||
OrMatcher permission = OrMatcher.create(
|
||||
new InvertMatcher(new DestinationPortMatcher(PORT + 1)));
|
||||
PolicyMatcher policyMatcher = new PolicyMatcher(POLICY_NAME, permission, principal);
|
||||
GrpcAuthorizationEngine engine = new GrpcAuthorizationEngine(
|
||||
new AuthConfig(Collections.singletonList(policyMatcher), Action.ALLOW));
|
||||
AuthDecision decision = engine.evaluate(new Metadata(), serverCall);
|
||||
assertThat(decision.decision()).isEqualTo(Action.ALLOW);
|
||||
assertThat(decision.matchingPolicyName()).isEqualTo(POLICY_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerMatcher_pathHeader() {
|
||||
AuthHeaderMatcher headerMatcher = new AuthHeaderMatcher(Matchers.HeaderMatcher
|
||||
.forExactValue(":path", "/" + PATH, false));
|
||||
OrMatcher principal = OrMatcher.create(headerMatcher);
|
||||
OrMatcher permission = OrMatcher.create(
|
||||
new InvertMatcher(new DestinationPortMatcher(PORT + 1)));
|
||||
PolicyMatcher policyMatcher = new PolicyMatcher(POLICY_NAME, permission, principal);
|
||||
GrpcAuthorizationEngine engine = new GrpcAuthorizationEngine(
|
||||
new AuthConfig(Collections.singletonList(policyMatcher), Action.ALLOW));
|
||||
AuthDecision decision = engine.evaluate(HEADER, serverCall);
|
||||
assertThat(decision.decision()).isEqualTo(Action.ALLOW);
|
||||
assertThat(decision.matchingPolicyName()).isEqualTo(POLICY_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerMatcher_aliasAuthorityAndHost() {
|
||||
AuthHeaderMatcher headerMatcher = new AuthHeaderMatcher(Matchers.HeaderMatcher
|
||||
.forExactValue("Host", "google.com", false));
|
||||
OrMatcher principal = OrMatcher.create(headerMatcher);
|
||||
OrMatcher permission = OrMatcher.create(
|
||||
new InvertMatcher(new DestinationPortMatcher(PORT + 1)));
|
||||
PolicyMatcher policyMatcher = new PolicyMatcher(POLICY_NAME, permission, principal);
|
||||
GrpcAuthorizationEngine engine = new GrpcAuthorizationEngine(
|
||||
new AuthConfig(Collections.singletonList(policyMatcher), Action.ALLOW));
|
||||
when(serverCall.getAuthority()).thenReturn("google.com");
|
||||
AuthDecision decision = engine.evaluate(new Metadata(), serverCall);
|
||||
assertThat(decision.decision()).isEqualTo(Action.ALLOW);
|
||||
assertThat(decision.matchingPolicyName()).isEqualTo(POLICY_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pathMatcher() {
|
||||
PathMatcher pathMatcher = new PathMatcher(STRING_MATCHER);
|
||||
|
|
|
|||
Loading…
Reference in New Issue