簡體   English   中英

Jersey / Grizzly的基本HTTP身份驗證

[英]Basic HTTP authentication with Jersey / Grizzly

我使用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 :如何向Jersey / Grizzly webapp添加基本HTTP身份驗證?

根據這篇博文 ,我設法讓它在幾個小時后運行起來

我的解決方案包括

  • 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);

您可能需要檢查與Jersey一起分發的HTTPS客戶端服務器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());
    }

您正在注冊一個SecurityFilter,它負責您的HTTP基本身份驗證。 在服務器上啟用日志記錄篩選器應在請求中顯示基本身份驗證標頭。 這是一個例子:

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

@aioobe要注意,雖然這將是一種很好的工作,但是當你使用標題時,你需要更好的錯誤檢查。 例如:

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

這假設認證頭是Basic,而它可能不是。 您應檢查授權標頭是否以“基本”開頭,如果沒有未經授權,則應檢查。 確保其余信息實際上是base64編碼的同樣的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM