users@grizzly.java.net

Aw: Re: Filtering a HTTP request

From: Pascal Klink <pascal.klink_at_web.de>
Date: Mon, 31 Mar 2014 21:33:10 +0200

Hi Oleksiy,

thankt you very much! That was exactly what I needed, because a Jersey filter was not applicable in my case (I also need to secure an instance of a StaticHttpHandler).

Greetings,
Pascal

 
_________________________________________________________________________________________________________________________________________________________________________ 

Gesendet: Sonntag, 30. März 2014 um 21:25 Uhr
Von: "Oleksiy Stashok" <oleksiy.stashok_at_oracle.com>
An: users_at_grizzly.java.net
Betreff: Re: Filtering a HTTP request
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();
}
}