10

JAX-RS、Jersey、および Grizzly を使用して単純な REST サーバーを作成しました。これは私がサーバーを起動する方法です:

URI baseUri = UriBuilder.fromUri("http://localhost/api")
                        .port(8081)
                        .build();

ResourceConfig rc = new PackagesResourceConfig("se.aioobe.resources");
HttpServer httpServer = GrizzlyServerFactory.createHttpServer(baseUri, rc);

ここで、基本 HTTP 認証を使用してリソースを保護する必要がありますが、その方法がわかりません。

動作させるのが簡単であれば、Grizzly からたとえば Jetty に切り替えることもできますが、Grizzly が提供するシンプルな構成/起動を本当に高く評価しています。

私はたくさんのチュートリアルを読みました。それらはすべて web.xml に言及していますが、現在の構成にはありません。(HTTP 認証用に追加する必要がありますか?)次の 質問を見つけましたが、どちらも役に立ちません :-(

(この時点では SSL は必要ありません。この時点での認証は、一般の人がベータ版をのぞき見するのを防ぐためのものです。)

TL;DR : 基本的な HTTP 認証を Jersey / Grizzly webapp に追加するにはどうすればよいですか?

4

3 に答える 3

12

このブログ投稿に基づいて、数時間後になんとか動作させることができました。

私の解決策は次のとおりです。

  • Maven アーティファクト:
    • ジャージサーバー (v 1.17)
    • jersey-grizzly2 (v 1.17)
  • ハードコードされたユーザー名/パスワード (必要に応じてデータベース ルックアップに置き換えます)
  • web.xml なし (プログラムで構成されたサーバー)
  • SSLは関係ありません

私はこれを作成しましたContainerRequestFilter

public class AuthFilter implements ContainerRequestFilter {

    // Exception thrown if user is unauthorized.
    private final static WebApplicationException unauthorized =
       new WebApplicationException(
           Response.status(Status.UNAUTHORIZED)
                   .header(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"realm\"")
                   .entity("Page requires login.").build());

    @Override
    public ContainerRequest filter(ContainerRequest containerRequest) 
            throws WebApplicationException {

        // Automatically allow certain requests.
        String method = containerRequest.getMethod();
        String path = containerRequest.getPath(true);
        if (method.equals("GET") && path.equals("application.wadl"))
            return containerRequest;

        // Get the authentication passed in HTTP headers parameters
        String auth = containerRequest.getHeaderValue("authorization");
        if (auth == null)
            throw unauthorized;

        auth = auth.replaceFirst("[Bb]asic ", "");
        String userColonPass = Base64.base64Decode(auth);

        if (!userColonPass.equals("admin:toHah1ooMeor6Oht"))
            throw unauthorized;

        return containerRequest;
    }
}

次に、起動コードを変更してフィルターを含めます。

URI baseUri = UriBuilder.fromUri("http://localhost/api")
                        .port(8081)
                        .build();

ResourceConfig rc = new PackagesResourceConfig("se.aioobe.resources");

// Add AuthFilter ////////////
rc.getProperties().put("com.sun.jersey.spi.container.ContainerRequestFilters",
                       "<YOUR PACKAGE FOR AuthFilter>.AuthFilter");
//////////////////////////////

HttpServer httpServer = GrizzlyServerFactory.createHttpServer(baseUri, rc);
于 2013-01-31T08:44:18.517 に答える
4

正確にそれを行うJerseyで配布されているHTTPS Client Server Grizzlyサンプルを確認することをお勧めします。これは、Grizzly サーバーでのセキュリティ フィルターの構成に関するサンプルの要点です。

    WebappContext context = new WebappContext("context");
    ServletRegistration registration = 
            context.addServlet("ServletContainer", ServletContainer.class);
    registration.setInitParameter("com.sun.jersey.config.property.packages",
            "com.sun.jersey.samples.https_grizzly.resource;com.sun.jersey.samples.https_grizzly.auth");

    // add security filter (which handles http basic authentication)
    registration.setInitParameter(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS,
            "com.sun.jersey.samples.https_grizzly.auth.SecurityFilter;com.sun.jersey.api.container.filter.LoggingFilter");
    registration.setInitParameter(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS,
            LoggingFilter.class.getName());


    try {

        webServer = GrizzlyServerFactory.createHttpServer(
                getBaseURI()
        );

        // start Grizzly embedded server //
        System.out.println("Jersey app started. Try out " + BASE_URI + "\nHit CTRL + C to stop it...");
        context.deploy(webServer);
        webServer.start();

    } catch (Exception ex) {
        System.out.println(ex.getMessage());
    }

HTTP 基本認証を処理する SecurityFilter を登録しています。サーバーでログ フィルターを有効にすると、要求に基本認証ヘッダーが表示されます。次に例を示します。

Jan 30, 2013 8:59:00 PM com.sun.jersey.api.container.filter.LoggingFilter filter
INFO: 1 * Server in-bound request
1 > GET http://localhost:8080/context/
1 > host: localhost:8080
1 > connection: keep-alive
1 > cache-control: max-age=0
1 > authorization: Basic dXNlcjpwYXNzd29yZA==
1 > accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
1 > user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
1 > accept-encoding: gzip,deflate,sdch
1 > accept-language: en-US,en;q=0.8
1 > accept-charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
1 > 

Service: GET / User: user
Jan 30, 2013 8:59:00 PM com.sun.jersey.api.container.filter.LoggingFilter$Adapter finish
INFO: 1 * Server out-bound response
1 < 200
1 < Content-Type: text/html
1 < 
JERSEY HTTPS EXAMPLE
于 2013-01-31T07:16:32.693 に答える
1

@aioobeは、これは一種の機能ですが、ヘッダーを操作するときはより良いエラーチェックが必要であることに注意してください。例えば:

    auth = auth.replaceFirst("[Bb]asic ", "");

これは、認証ヘッダーが Basic であることを前提としていますが、そうでない場合もあります。認証ヘッダーが「Basic」で始まっていることを確認し、そうでない場合は無許可をスローする必要があります。残りの情報が実際にbase64でエンコードされていることを確認するための同じこと.

于 2013-01-31T19:18:15.323 に答える