gRPC interceptors with Java

In this article we are going to explore about gRPC interceptors and will implement and show the working of gRPC interceptors with Java.

Interceptors in gRPC

In gRPC there are 2 type of interceptors available, one is a unary interceptor and another one is a stream interceptor

These unary and stream interceptors again classified into two types of interceptor . One is the Client interceptor another is the server interceptor

gRPC Client Interceptors

Client Interceptor is used with channels in gRPC. If we want to add some additional data before making a call to the server then we can do that with the help of the client interceptor. with client interceptors, we can add data like authorization tokens or anything else in metadata and send it to the server.

gRPC Server Interceptors

Server Interceptor is used with server in gRPC. Server Interceptors in gRPC intercept all incoming requests to the server. With help of server interceptors, we can check the details and decide whether we are allowing to access the resource or we are rejecting the request, so we can also use server interceptors for authorization in gRPC.

gRPC Server Interceptor Implementation

Here we are going to add a server interceptor in our previous gRPC project implemented in Java, you can check that with this link https://thecodedata.com/grpc-with-java/ and download the project.

Add following dependencies in pom.xml for JWT Token

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>

now Let’s create a server interceptor class by implementing ServerInterceptor and override “ServerCall.Listener” to validate the JWT token

serverInterceptor.java

import io.grpc.*;
import io.jsonwebtoken.*;

import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;

public class serverInterceptor implements ServerInterceptor {

    private JwtParser jwtParser = Jwts.parser().setSigningKey("grpc server with java");
    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {

        String token = metadata.get(Metadata.Key.of("Token",ASCII_STRING_MARSHALLER));
        Status status = Status.OK;

        if(token==null)
            status = Status.UNAUTHENTICATED.withDescription("Token is missing");
        else if(!token.startsWith("Bearer"))
            status = Status.UNAUTHENTICATED.withDescription("unknown authorization token type");
        else {
            Jws<Claims> claimsJws = null;
            try {
                claimsJws = jwtParser.parseClaimsJws(token.substring(6).trim());
            } catch (JwtException e) {
                status = Status.UNAUTHENTICATED.withDescription(e.getMessage()).withCause(e);
            }
            if(claimsJws!=null)
            {
                Context context = Context.current().withValue(Context.key("TokenData"),
                        claimsJws.getBody().getSubject());
                return Contexts.interceptCall(context,serverCall,metadata,serverCallHandler);
            }
        }
        serverCall.close(status, new Metadata());
            return new ServerCall.Listener<ReqT>() {
            };
        }
    }

now we have to add this serverInterceptor on server

Server.java updated code

import io.grpc.ServerBuilder;
import service.ServiceImpl;

import java.io.IOException;

public class Server {
    public static void main(String[] args) throws IOException, InterruptedException {
        int port = 8000;
        io.grpc.Server server = ServerBuilder.forPort(port).addService(new ServiceImpl())
                .intercept(new serverInterceptor()).build().start();
        System.out.println("server started at port: "+port );
        server.awaitTermination();
    }
}

JWT Server Interceptor Response

let’s try to access the endpoint without adding the Proper JWT token in metadata from BloomRPC

grpc server interceptor

we got this response because we did not added the JWT token in the metadata and our requested call is rejected by gRPC server Interceptor .

Now let’s generate a JWT token with same signing key and add it to metadata with key name “Token”

grpc java tutorial

Here we are getting a response because we are given the correct Jwt token.

if the token is expired or there are any changes, then we did not get a response from the server. following is the case bellowed where the JWT token is expired

grpc java interceptor

You can download the entire project using this link

Thanks !!!

1 thought on “gRPC interceptors with Java”

Leave a Comment