Skip to content

Static authorization server interceptor implementation #8934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Resolving comments
  • Loading branch information
ashithasantosh committed Jun 8, 2022
commit 3a0b5e5902c174ccf2e978b1bb4e4f53a357bc8f
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
import static com.google.common.base.Preconditions.checkNotNull;

import io.envoyproxy.envoy.config.rbac.v3.RBAC;
import io.grpc.InternalServerInterceptors;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.Status;
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine;
import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine.AuthDecision;
import io.grpc.xds.internal.rbac.engine.RbacParser;
import io.grpc.xds.ConfigOrError;
import io.grpc.xds.RbacConfig;
import io.grpc.xds.RbacFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -35,10 +35,10 @@
* Authorization server interceptor for static policy.
*/
public final class AuthorizationServerInterceptor implements ServerInterceptor {
private final List<GrpcAuthorizationEngine> rbacEngines = new ArrayList<>();
private final List<ServerInterceptor> interceptors = new ArrayList<>();

List<GrpcAuthorizationEngine> getEngines() {
return rbacEngines;
int getInterceptorsCount() {
return interceptors.size();
}

private AuthorizationServerInterceptor(String authorizationPolicy)
Expand All @@ -48,22 +48,22 @@ private AuthorizationServerInterceptor(String authorizationPolicy)
throw new IllegalArgumentException("Failed to create authorization engines");
}
for (RBAC rbac: rbacs) {
rbacEngines.add(new GrpcAuthorizationEngine(RbacParser.parseRbac(rbac)));
ConfigOrError<RbacConfig> filterConfig = new RbacFilter().parseRbacConfig(
io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBAC.newBuilder()
.setRules(rbac).build());
if (filterConfig.errorDetail != null) {
throw new IllegalArgumentException("Rbac config is invalid");
}
interceptors.add(new RbacFilter().buildServerInterceptor(filterConfig.config, null));
}
}

@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call, Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
for (GrpcAuthorizationEngine rbacEngine: rbacEngines) {
AuthDecision authDecision = rbacEngine.evaluate(headers, call);
if (GrpcAuthorizationEngine.Action.DENY.equals(authDecision.decision())) {
Status status =
Status.PERMISSION_DENIED.withDescription("Unauthorized RPC request rejected");
call.close(status, new Metadata());
return new ServerCall.Listener<ReqT>(){};
}
for (ServerInterceptor interceptor: interceptors) {
next = InternalServerInterceptors.interceptCallHandlerCreate(interceptor, next);
}
return next.startCall(call, headers);
}
Expand Down
10 changes: 5 additions & 5 deletions authz/src/test/java/io/grpc/authz/AuthorizationEnd2EndTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public void staticAuthzDeniesRpcNoMatchInDenyAndAllowTest() throws Exception {
fail("exception expected");
} catch (StatusRuntimeException sre) {
assertThat(sre).hasMessageThat().isEqualTo(
"PERMISSION_DENIED: Unauthorized RPC request rejected");
"PERMISSION_DENIED: Access Denied");
} catch (Exception e) {
throw new AssertionError("the test failed ", e);
}
Expand Down Expand Up @@ -194,7 +194,7 @@ public void staticAuthzDeniesRpcMatchInDenyAndAllowTest() throws Exception {
fail("exception expected");
} catch (StatusRuntimeException sre) {
assertThat(sre).hasMessageThat().isEqualTo(
"PERMISSION_DENIED: Unauthorized RPC request rejected");
"PERMISSION_DENIED: Access Denied");
} catch (Exception e) {
throw new AssertionError("the test failed ", e);
}
Expand Down Expand Up @@ -242,7 +242,7 @@ public void staticAuthzDeniesRpcMatchInDenyNoMatchInAllowTest() throws Exception
fail("exception expected");
} catch (StatusRuntimeException sre) {
assertThat(sre).hasMessageThat().isEqualTo(
"PERMISSION_DENIED: Unauthorized RPC request rejected");
"PERMISSION_DENIED: Access Denied");
} catch (Exception e) {
throw new AssertionError("the test failed ", e);
}
Expand Down Expand Up @@ -310,7 +310,7 @@ public void staticAuthzDeniesRpcEmptyDenyNoMatchInAllowTest() throws Exception {
fail("exception expected");
} catch (StatusRuntimeException sre) {
assertThat(sre).hasMessageThat().isEqualTo(
"PERMISSION_DENIED: Unauthorized RPC request rejected");
"PERMISSION_DENIED: Access Denied");
} catch (Exception e) {
throw new AssertionError("the test failed ", e);
}
Expand Down Expand Up @@ -347,7 +347,7 @@ public void staticAuthzDeniesRpcWithPrincipalsFieldOnUnauthenticatedConnectionTe
fail("exception expected");
} catch (StatusRuntimeException sre) {
assertThat(sre).hasMessageThat().isEqualTo(
"PERMISSION_DENIED: Unauthorized RPC request rejected");
"PERMISSION_DENIED: Access Denied");
} catch (Exception e) {
throw new AssertionError("the test failed ", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import io.grpc.xds.internal.rbac.engine.GrpcAuthorizationEngine;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
Expand Down Expand Up @@ -66,7 +64,6 @@ public void validPolicyCreatesStaticAuthzInterceptor() throws Exception {
+ " ]"
+ "}";
AuthorizationServerInterceptor interceptor = AuthorizationServerInterceptor.create(policy);
List<GrpcAuthorizationEngine> engines = interceptor.getEngines();
assertEquals(engines.size(), 2);
assertEquals(interceptor.getInterceptorsCount(), 2);
}
}
6 changes: 3 additions & 3 deletions xds/src/main/java/io/grpc/xds/ConfigOrError.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

// TODO(zdapeng): Unify with ClientXdsClient.StructOrError, or just have parseFilterConfig() throw
// certain types of Exception.
final class ConfigOrError<T> {
public final class ConfigOrError<T> {

/**
* Returns a {@link ConfigOrError} for the successfully converted data object.
Expand All @@ -36,8 +36,8 @@ static <T> ConfigOrError<T> fromError(String errorDetail) {
return new ConfigOrError<>(errorDetail);
}

final String errorDetail;
final T config;
public final String errorDetail;
public final T config;

private ConfigOrError(T config) {
this.config = checkNotNull(config, "config");
Expand Down
2 changes: 1 addition & 1 deletion xds/src/main/java/io/grpc/xds/RbacConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

/** Rbac configuration for Rbac filter. */
@AutoValue
abstract class RbacConfig implements FilterConfig {
public abstract class RbacConfig implements FilterConfig {
@Override
public final String typeUrl() {
return RbacFilter.TYPE_URL;
Expand Down
Loading