users@grizzly.java.net

Re: Filtering a HTTP request

From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
Date: Sun, 30 Mar 2014 12:25:15 -0700

Hi Pascal,


On 30.03.14 10:58, Pascal Klink wrote:
> Hi everyone,
>
> I started using Grizzly with Jersey in order to create a web service which works on a DB. This Server publishes an admin and a public endpoint.
> While the public endpoint can be accessed without any authentication, the admin endpoint uses SSL to authenticate (both client and server).
> Naturally I don't want the public endpoint to have access on my admin HttpHandler so what I need is a Filter which permits the access on the admin HttpHandler from the public NetworkListener.
> So I created an AddOn which is then added to my public NetworkListener. And from that point I'm having problems finishing my filter.
>
> The first thing is, that I don't know where to place the Filter in the FilterChain. I tried to place it after the HttpCodecFilter but the problem is, that I could not get the full address of the request (I only got localhost:19240 instead of localhost:19240/admin, which I would need to check if the admin Handler should be accessed).
> The second thing is, that I don't know which of the methods of the Filter Interface I need to implement in order to make the Filter work correctly.
If you want to implement Grizzly Filter - it may look like [1].

> So my question is - can anybody help me out here? I read the documentation but it didn't help me figuring out the answer to the questions above.
I'd also recommend to take a look at Jersey Filters, may be they'll fit
better, if not - we can definitely implement it as Grizzly Filter.

Thanks.

WBR,
Alexey.

[1] public static class MyFilter extends BaseFilter {
         private static final Attribute<Boolean> ADMIN_ACCESS_CHECK =
AttributeBuilder.DEFAULT_ATTRIBUTE_BUILDER.<Boolean>createAttribute("checked");


         @Override
         public NextAction handleRead(FilterChainContext ctx) throws
IOException {
             // Get the connection
             final Connection c = ctx.getConnection();
             // Get the message
             final HttpContent httpMessage = ctx.getMessage();
             // Get the HTTP request headers
             final HttpRequestPacket request =
                     (HttpRequestPacket) httpMessage.getHttpHeader();

             // retrieve request URI
             final String uri = request.getRequestURI();

             if ("/admin".equals(uri)) {
                 // if the Connection has been checked already - just
continue processing
                 if (Boolean.TRUE.equals(ADMIN_ACCESS_CHECK.get(c))) {
                     return ctx.getInvokeAction();
                 }

                 // make sure the requesst is secured
                 if (request.isSecure()) {
                     // Get SSLEngine associated with the Connection and
check the certificate
                     final SSLEngine sslEngine = SSLUtils.getSSLEngine(c);
                     final X509Certificate[] certs
                             =
sslEngine.getSession().getPeerCertificateChain();
                     if (certs.length > 0) {
                         if (checkCertificate(certs[0])) {
                             ADMIN_ACCESS_CHECK.set(c, Boolean.TRUE);
                             return ctx.getInvokeAction();
                         }
                     }
                 }

                 // if the certificate checking failed - return 403 and
close the Connection
                 ctx.write(HttpResponsePacket.builder(request)
.status(HttpStatus.FORBIDDEN_403.getStatusCode())
                         .protocol(Protocol.HTTP_1_1)
                         .contentLength(0)
                         .build()
                     );
                 c.closeSilently();

                 return ctx.getStopAction();
             }


             return ctx.getInvokeAction();
         }
     }