14

我创建了一些 JAX-RS 2.0 资源(使用在 Servlet 容器中运行的 Jeresey 2.4)和一个处理身份验证和授权的过滤器,可以通过 @NameBinding 注释有选择地应用这些资源。这一切都很好。

我希望能够在此注释上定义一些参数(特别是访问每个方法/资源所需的安全权限),这些参数可用于过滤器在运行时更改此行为。

我注意到拦截器可以通过 javax.ws.rs.ext.InterceptorContext.getAnnotations() 执行此操作,但 javax.ws.rs.container.ContainerRequestContext 中没有过滤器的等效项。任何想法如何实现?我希望能够执行以下操作:

@Target({TYPE, METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@NameBinding
public @interface Secured {
    String[] requiredPermissions() default {};
}

@Secured
@Priority(Priorities.AUTHENTICATION)
public class SecurityRequestFilter implements ContainerRequestFilter {
    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
        // extract credentials, verify them and check that the user has required permissions, aborting if not
    }
}

@Path("/userConfiguration/")
public class UserConfigurationResource {
    @GET
    @Produces(MediaType.APPLICATION_XML)
    @Secured(requiredPermissions = {"configuration-permission"})
    public Response getConfig(@Context HttpServletRequest httpServletRequest) {
        // produce a response
    }
}
4

2 回答 2

13

对于非供应商特定的解决方案,自 JAX-RS 2.0 起,您可以使用ResourceInfo

@Secured
@Priority(Priorities.AUTHENTICATION)
public class SecurityRequestFilter implements ContainerRequestFilter {

    @Context
    private ResourceInfo resourceInfo;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        Method method = resourceInfo.getResourceMethod();

        if (method != null) {
            Secured secured = method.getAnnotation(Secured.class);
            ...
        }
    }
}
于 2015-09-28T10:10:38.833 回答
7

您可以从UriInfo获取此信息,尤其是它的(特定于泽西的)ExtendedUriInfo子接口。要获取实例,请调用ContainerRequestContext#getUriInfo()并进行转换

final ExtendedUriInfo extendendUriInfo = (ExtendedUriInfo) containerRequestContext.getUriInfo();

或将其注入您的过滤器:

@Inject
private ExtendedUriInfo extendendUriInfo;

然后

extendedUriInfo
    .getMatchedResourceMethod()
    .getInvocable()
    .getHandlingMethod().getAnnotation(Secured.class);

在第二种方法中,您可以实现DynamicFeature并将您的过滤器仅分配给特定的资源方法(即,如果过滤器的配置更复杂,过滤器仅适用于几个方法并且您希望减少开销,... )。看看RolesAllowedDynamicFeature的实现,它增加了对 Jersey 中资源方法的安全注释的支持。

于 2013-11-05T20:53:31.353 回答