如何创建受保护的Restlet资源?

时间:2017-01-17 08:42:52

标签: java web-services restlet

我正在尝试根据此示例创建受保护的Restlet资源http://bipinkunjumon.blogspot.com/2013/05/restlet-application-for-accessing.html

public class PartApp extends Application {
public  static  final  String  ROOT_URI="localhost:8151/accounts/{accountId}";
public static void main(String[] args) throws Exception
{
    // Create a component
    Component component = new Component();
    component.getServers().add(Protocol.HTTP, 8151);
    component.getClients().add(Protocol.FILE);

    // Create an application
    Application application = new PartApp();

    // Attach the application to the component and start it
    component.getDefaultHost().attachDefault(application);
    component.start();
}

@Override
public Restlet createInboundRoot()
{
    // Create a simple password verifier
    MapVerifier verifier = new MapVerifier();
    verifier.getLocalSecrets().put("scott", "tiger".toCharArray());



    // Create a Guard
    ChallengeAuthenticator authenticator = new ChallengeAuthenticator(
            getContext(), ChallengeScheme.HTTP_BASIC, "Tutorial");
    authenticator.setVerifier(verifier);

    // Create a Directory able to return a deep hierarchy of files
    Directory directory = new Directory(getContext(), ROOT_URI);

    directory.setListingAllowed(true);
    authenticator.setNext(directory);
    return authenticator;
}
}

但它适用于所有服务器资源。例如,如果没有登录名和密码,我无法输入localhost:8111。但是我只需要保护一个资源:localhost:8151 / accounts / {accountId}并为其他资源提供免费访问。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

基于我在此处找到的代码:https://stackoverflow.com/a/2220624/444028, 我使用 Java 7 Restlet SE 2.3.9 创建了这个小项目:

此项目中有2个包中有6个java文件(全部是服务器端代码):

  1. com.blogspot.javarestlet.httpbasicauth.server.app
    1. AdminAppStart.java(授权客户端的应用程序扩展)
    2. ClientAppStart.java(未授权客户端的应用程序扩展)[注意:这不是客户端代码。]
    3. Main.java(运行服务器的那个)
    4. com.blogspot.javarestlet.httpbasicauth.server.resources
      1. HelloWorldAdminServerResource.java(与AdminAppStart连接)
      2. HelloWorldClientServerResource.java(与ClientAppStart连接)
      3. HelloWorldDefaultServerResource.java(一个有点不必要的类文件)
      4. 以下是每个文件的代码:

        AdminAppStart.java

        package com.blogspot.javarestlet.httpbasicauth.server.app;
        
        import org.restlet.Application;
        import org.restlet.Context;
        import org.restlet.Restlet;
        import org.restlet.data.ChallengeScheme;
        import org.restlet.routing.Router;
        import org.restlet.security.ChallengeAuthenticator;
        import org.restlet.security.MapVerifier;
        
        import com.blogspot.javarestlet.httpbasicauth.server.resources.HelloWorldAdminServerResource;
        import com.blogspot.javarestlet.httpbasicauth.server.resources.HelloWorldDefaultServerResource;
        
        public class AdminAppStart extends Application {
            private ChallengeAuthenticator authenticator;
        
            private ChallengeAuthenticator createAuthenticator() {
                Context context = getContext();
                final boolean optional = false;
                ChallengeScheme challengeScheme = ChallengeScheme.HTTP_BASIC;
                String realm = "Example site";
        
                MapVerifier verifier = new MapVerifier();
                verifier.getLocalSecrets().put("scott", "tiger".toCharArray());
        
                ChallengeAuthenticator auth = new ChallengeAuthenticator(context, optional, challengeScheme, realm, verifier);
                return auth;
            }
        
            @Override
            public Restlet createInboundRoot() {
                this.authenticator = createAuthenticator();
        
                Router router = new Router();
                router.attach("/user", HelloWorldAdminServerResource.class);
                router.attach("", HelloWorldDefaultServerResource.class);
        
                authenticator.setNext(router);
                return authenticator;
            }
        
        }
        

        ClientAppStart.java

        package com.blogspot.javarestlet.httpbasicauth.server.app;
        
        import org.restlet.Application;
        import org.restlet.Restlet;
        import org.restlet.routing.Router;
        
        import com.blogspot.javarestlet.httpbasicauth.server.resources.HelloWorldClientServerResource;
        
        public class ClientAppStart extends Application {
        @Override
        public Restlet createInboundRoot() {
            Router router = new Router();
            router.attach("/clientres/hello", HelloWorldClientServerResource.class);
            return router;
        }
        }
        

        Main.java

        package com.blogspot.javarestlet.httpbasicauth.server.app;
        
        import org.restlet.Application;
        import org.restlet.Component;
        import org.restlet.data.Protocol;
        
        public class Main {
            public static void main(String[] args) throws Exception
            {
                // Create a component
                Component component = new Component();
                component.getServers().add(Protocol.HTTP, 8151);
                component.getClients().add(Protocol.HTTP);
        
                // Create an application
                Application application = new ClientAppStart();
        
                // Attach the application to the component and start it
                component.getDefaultHost().attach("/userx",application);
                component.getDefaultHost().attach("/admin/accounts/abc123",new AdminAppStart());
                component.start();
            }
        }
        

        HelloWorldAdminServerResource.java

        package com.blogspot.javarestlet.httpbasicauth.server.resources;
        
        import org.restlet.resource.Get;
        import org.restlet.resource.ServerResource;
        
        public class HelloWorldAdminServerResource  extends ServerResource {
            @Get
            public String $get()
            {
                return "Hello Admin";
            }
        }
        

        HelloWorldClientServerResource.java

        package com.blogspot.javarestlet.httpbasicauth.server.resources;
        
        import org.restlet.resource.Get;
        import org.restlet.resource.ServerResource;
        
        public class HelloWorldClientServerResource extends ServerResource {
        @Get
        public String $get()
        {
            return "Hello Client";
        }
        }
        

        HelloWorldDefaultServerResource.java

        package com.blogspot.javarestlet.httpbasicauth.server.resources;
        
        import org.restlet.resource.Get;
        import org.restlet.resource.ServerResource;
        
        public class HelloWorldDefaultServerResource extends ServerResource{
        @Get
        public String $get()
        {
            return "please enter a sub-url after abc123";
        }
        }
        

        以下是cURL请求 - 响应日志:

        C:\Users\abhishek>curl -i "http://localhost:8151/userx/clientres/hello"
        HTTP/1.1 200 OK
        Content-type: text/plain; charset=UTF-8
        Content-length: 12
        Server: Restlet-Framework/2.3.9
        Accept-ranges: bytes
        Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
        Date: Mon, 23 Jan 2017 11:37:01 GMT
        
        Hello Client
        
        ======================================================================
        
        C:\Users\abhishek>curl -i -H "Authorization: Basic c2NvdHQ6dGlnZXI=" "http://localhost:8151/admin/accounts/abc123"
        HTTP/1.1 200 OK
        Content-type: text/plain; charset=UTF-8
        Content-length: 35
        Server: Restlet-Framework/2.3.9
        Accept-ranges: bytes
        Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
        Date: Mon, 23 Jan 2017 11:35:07 GMT
        
        please enter a sub-url after abc123
        
        ======================================================================
        
        C:\Users\abhishek>curl -i -H "Authorization: Basic c2NvdHQ6dGlnZXI=" "http://localhost:8151/admin/accounts/abc123/user"
        HTTP/1.1 200 OK
        Content-type: text/plain; charset=UTF-8
        Content-length: 11
        Server: Restlet-Framework/2.3.9
        Accept-ranges: bytes
        Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
        Date: Mon, 23 Jan 2017 11:35:04 GMT
        
        Hello Admin
        
        ======================================================================
        
        C:\Users\abhishek>curl -i "http://localhost:8151/admin/accounts/abc123/user"
        HTTP/1.1 401 Unauthorized
        Content-type: text/html; charset=UTF-8
        Content-length: 424
        Www-authenticate: Basic realm="Example site"
        Server: Restlet-Framework/2.3.9
        Accept-ranges: bytes
        Date: Mon, 23 Jan 2017 12:48:08 GMT
        
        <html>
        <head>
           <title>Status page</title>
        </head>
        <body style="font-family: sans-serif;">
        <p style="font-size: 1.2em;font-weight: bold;margin: 1em 0px;">Unauthorized</p>
        <p>The request requires user authentication</p>
        <p>You can get technical details <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">here</a>.<br>
        Please continue your visit at our <a href="/">home page</a>.
        </p>
        </body>
        </html>
        

        试试这个并告诉我们您是否遇到任何问题。

        已于2017-01-24 1524添加:

        由于提问者已经问过“.. 通过创建单独的应用程序来做这样的事情这是常见的规则吗?”

        以下是最简单的简要回答:

        Application.createInboundRoot()应该返回Restlet,这里是从这里获得的Restlet类的子类:https://restlet.com/technical-resources/restlet-framework/javadocs/2.3/jee/api/

        org.restlet.Restlet
        ^
        |
        |--org.restlet.Application
        |
        |--org.restlet.Component
        |
        |--org.restlet.Connector
        |  ^
        |  |--org.restlet.Client
        |  |
        |  |--org.restlet.Server
        |
        |--org.restlet.routing.Filter
        |  ^
        |  |
        |  |--org.restlet.security.Authenticator
        |  |  ^
        |  |  |
        |  |  |--org.restlet.security.CertificateAuthenticator
        |  |  |
        |  |  |--org.restlet.security.ChallengeAuthenticator
        |  |
        |  |--org.restlet.security.Authorizer
        |  |  ^
        |  |  |
        |  |  |--org.restlet.security.ConfidentialAuthorizer
        |  |  |
        |  |  |--org.restlet.security.MethodAuthorizer
        |  |  |
        |  |  |--org.restlet.security.RoleAuthorizer
        |  |
        |  |--org.restlet.routing.Extractor
        |  |
        |  |--org.restlet.routing.Route
        |  |  ^
        |  |  |
        |  |  |--org.restlet.routing.TemplateRoute
        |  |
        |  |--org.restlet.routing.Validator
        |
        |--org.restlet.resource.Finder
        |  ^
        |  |
        |  |--org.restlet.resource.Directory
        |
        |--org.restlet.routing.Redirector
        |
        |--org.restlet.routing.Router
        |
        |--org.restlet.util.WrapperRestlet
        

        如果你浏览每个类的文档和样本(每个类都会使这个答案太长),你会发现有其他方法可以做到这一点,但是为每个类创建单独的Application是最简单的各种方式。