java - 使用 Guice 将委托(delegate)人注入(inject) RESTEasy 中的资源方法

标签 java rest guice code-injection resteasy

我正在使用 RESTEasy 和 Guice 开发 REST API,目前我正在尝试通过使用类似于 Dropwizard 中的 @Auth 的注释来合并基本身份验证。与

@Path("hello")
public class HelloResource {
    @GET
    @Produces("application/json")
    public String hello(@Auth final Principal principal) {
        return principal.getUsername();
    }
}

hello 资源调用应该被一些代码拦截,这些代码使用授权 HTTP 请求 header 中传递的凭据执行基本身份验证,并成功将主体注入(inject)方法主体参数。我还希望能够将允许的角色列表传递给注释,例如@Auth("admin")

我真的需要一些关于实现这一目标的方向的建议吗?

最佳答案

我认为您最好的选择是在请求范围内使用中间值。假设你没有输入 HelloResource在单例范围内,你可以在一些 ContainerRequestFilter 中注入(inject)这个中间值实现并在您的资源中,您可以将其填写在此 ContainerRequestFilter 中使用您需要的所有身份验证和授权信息实现。

它看起来像这样:

// Authentication filter contains code which performs authentication
// and possibly authorization based on the request
@Provider
public class AuthFilter implements ContainerRequestFilter {
    private final AuthInfo authInfo;

    @Inject
    AuthFilter(AuthInfo authInfo) {
        this.authInfo = authInfo;
    }

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        // You can check request contents here and even abort the request completely
        // Fill authInfo with the data you need
        Principal principal = ...;  // Ask some other service possibly
        authInfo.setPrincipal(principal);
    }
}

@Path("hello")
public class HelloResource {
    private final AuthInfo authInfo;

    @Inject
    HelloResource(AuthInfo authInfo) {
        this.authInfo = authInfo;
    }

    @GET
    @Produces("application/json")
    public String hello() {
        // authInfo here will be pre-filled with the principal, assuming
        // you didn't abort the request in the filter
        return authInfo.getPrincipal().getUsername();
    }
}

public class MainModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(AuthFilter.class);
        bind(HelloResource.class);
        bind(AuthInfo.class).in(RequestScoped.class);
    }
}

即使您出于某种原因确实将资源(甚至过滤器)放入单例范围内,您也始终可以注入(inject) Provider<AuthInfo>而不是 AuthInfo .

更新

看来我有点不对,因为过滤器默认不在单例范围内。事实上,它似乎表现得像单例,即使它没有被绑定(bind)。它是在 JAX-RS 容器启动时创建的。因此你需要注入(inject) Provider<AuthInfo>进入过滤器。事实上,如果AuthInfo,容器启动将失败。在绑定(bind)到请求范围时直接注入(inject)到过滤器中。资源(如果未明确绑定(bind)为单例)可以直接注入(inject)。

我已经上传工作程序到github .

关于java - 使用 Guice 将委托(delegate)人注入(inject) RESTEasy 中的资源方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21018828/

相关文章:

c# - Transactionscope 和 webHttpBinding

java - 使用 Dagger 2 的自定义注解拦截器

java - 注入(inject)由枚举值键控的接口(interface)实现映射

java - 为什么oracle存储过程执行时间根据它的执行方式大大增加?

java - 最小化 GWT 应用程序的编译大小

Java IF ELSE 语句

java - JsonIdentityInfo 用于 hibernate 映射

REST API 设计 - 单个通用端点或多个特定端点

java - mybatis-guice mysql 加载jdbc驱动失败

java - 文本框中的文本