Restelet路由:一些资源需要身份验证,有些则不需要。怎么做?

时间:2014-02-14 01:49:41

标签: authentication url-routing restlet restlet-2.0

我一直在研究RESTlet 2.1项目。我已经弄清楚如何为我的资源设置身份验证。事实是..并非所有人都需要身份验证!我很困惑,我应该怎么做。

在下面的代码中,您可以看到我的服务器应用程序的大纲,特别是“创建入站根”:

@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;

}

过滤器必须在所有内容之前,因为我需要为所有包修改一些Headers。在过滤器之后,我想设置一个fork,其中我的公共资源的请求只被路由到Resource类,私有资源的请求必须通过验证器。

我怎样才能做到这一点?我是这个框架的新手,即使它看起来很简单也无法弄明白。

2 个答案:

答案 0 :(得分:2)

将您的路由器视为链条。你看起来像这样:

someFilter - >验证者 - >路由器 - > (SomeResource.class | PrivateResource.class)

这意味着所有请求都从someFilter开始,通过身份验证器,点击路由器并最终到达SomeResource或PrivateResource。

您需要将身份验证器放在PrivateResource前面,将身份验证器移动到链的那一位,所以看起来更像是这样:

someFilter - >路由器 - > (SomeResource.class | authenticator - > PrivateResource.class)

代码可能如下所示:

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

这有帮助吗?

答案 1 :(得分:0)

我已经找到了完整的解决方案,它是关于" URI模板"。缺少的一件事是路由器可以匹配uri的不同方式,事实上,问题需要一个"匹配URI的第一部分"一种方法。

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

如果URL以/ public或/ private:

开头,routerPP将做出决定
    Router routerPP = new Router(getContext());
    routerPP.setDefaultMatchingMode(Template.MODE_STARTS_WITH);
    routerPP.attach("/private", authenticator);
    routerPP.attach("/public", publicR);

一个特殊性是,在URL"经过"路由器,它会丢失URL的匹配部分,因此后续路由器(例如公共路由器)将具有以下结构:

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

并且此类配置与以下URL匹配:     http://somehost.com/public/somePublicResource

如果在第二个路由器中添加" / public /"令牌再次出现,您将获得未找到的资源"错误,然后资源将打开:http://somehost.com/public/public/somePublicResource

所以路由器匹配并从URL中删除。

有关我认为有用的路由和URI匹配的参考:

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