java - 使用 Jersey/Grizzly 的基本 HTTP 身份验证

标签 java jersey jax-rs http-authentication 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 身份验证添加一个吗?)我找到了 following questions , 它们都没有任何帮助:-(

(此时不需要 SSL。此时的身份验证只是为了防止公众偷看我们的测试版。)

TL;DR:如何向 Jersey/Grizzly 网络应用程序添加基本 HTTP 身份验证?

最佳答案

基于 this blog post,我在几个小时后设法让它工作了.

我的解决方案包括:

  • Maven 工件:
    • Jersey 服务器(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);

关于java - 使用 Jersey/Grizzly 的基本 HTTP 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14608162/

相关文章:

java - 为什么这个使用 Collections.sort 的程序只对大小为 32 或更大的列表失败?

java - JAX-RS:Stateless、Singleton、RequestScoped 混淆

java - 将字符串值从 Activity 类传递到非 Activity 类

java - 将 JLabel/JPanel 添加到 Scala Swing Panel 时出现类型不匹配错误

java - REST:客户端可以通过 POST 传递包装对象吗?

java - 如何从带有 Jersey 的多部分表单中读取具有相同名称的多个(文件)输入?

java - 如何在 REST Web 服务中使用 json 生成 http 响应?

java - JaxRS + RestEasy - 如何创建自己的 @Context 注入(inject)字段?

java - 如何用 java 将文件上传到 Restful Web 服务?

java - 计算数组中单词的出现次数