質問

I've been workin on a RESTlet 2.1 project. I've figured out how to set up authentication for my Resources. Fact is.. not all of them need authentication! I am quite puzzled about how should I do it right.

In the following code you can see the outline of my server Application, in particular the "create Inbound Root":

@Override
public Restlet createInboundRoot(){

    /* the structure so far is: a filter, followed by an authenticator,
       followed by a rooter. 
       The filter is returned at end of the method.
    */


    //Init filter:
    SomeFilter someFilter = new SomeFilter();


            //Init authenticator:
    ChallengeAuthenticator authenticator = new ChallengeAuthenticator(
        ......);
    //more authenticator stuff goes here....        


    //Init router:
    Router router = new Router(getContext());
    //this should be a public resource, no need for auth:
    router.attach("/0.1/getResource", SomeResource.class)
    //this is a private resource, needs auth:
    router.attach("/0.1/getPrivateResource", PrivateResource.class);

    //set up the flow: filter -> authenticator -> router
    authenticator.setNext(router);      
    someFilter.setNext(authenticator);
    return someFilter;

}

The filter must be before everything, since I need to modify some Headers for all packages. After the filter I would like to set-up a fork, where requests of my public resource are just routed to the Resource class and requests of the private resource must pass through the authenticator.

How can I accomplish this? I am new to this framework and couldn't figure out even if it looks dead simple.

役に立ちましたか?

解決 2

I've figured out the full solution to this, it was about "URI templates". The one thing missing was the different way a router can match the uri, in fact, the problem needed a "Match the first part of the URI" kind of approach.

    /*
     * Routing structure:
     * 
     *                            ---/public---->(publicR()----> Public Resources
     * (Filter()---->(routerPP()--|
     *                            ---/private--->(authenticator()---->(privateR()---> Private Resources
     *       
     */

where routerPP takes the decision if the URL begins with /public or /private:

    Router routerPP = new Router(getContext());
    routerPP.setDefaultMatchingMode(Template.MODE_STARTS_WITH);
    routerPP.attach("/private", authenticator);
    routerPP.attach("/public", publicR);

the one particularity is that, after an URL "passes through" a router, it looses the matched part of the URL, therefore a following router (e.g. the public one) will have this structure:

    Router publicR = new Router(getContext());
    publicR.attach("/somePublicResource", SomePublicResource.class);

and such configuration matches the following URL: http://somehost.com/public/somePublicResource

if in the second router you add the "/public/" token again, you will get a "resource not found" error, and the resource would then be on: http://somehost.com/public/public/somePublicResource

So the routers match and remove from the URL.

Reference about the routing and the URI matching I've found useful are:

http://restlet-discuss.1400322.n2.nabble.com/Trying-to-route-to-two-routes-that-start-with-same-prefix-td7019794.html

http://restlet.org/learn/javadocs/snapshot/jse/api/org/restlet/routing/Router.html

他のヒント

Think about your routers like a chain. Yours look like this:

someFilter -> authenticator -> router -> (SomeResource.class | PrivateResource.class)

This means all requests start at someFilter, go through the authenticator, hit the router and end up at either SomeResource or PrivateResource.

You need to put the authenticator in front of PrivateResource only, move the authenticator to that bit of the chain, so it looks more like this:

someFilter -> router -> (SomeResource.class | authenticator -> PrivateResource.class)

The code might look like:

   ChallengeAuthenticator authenticator = new ChallengeAuthenticator(......);
   authenticator.setNext(PrivateResource.class);
   router.attach("/0.1/getPrivateResource", authenticator);

Does that help?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top