Jax-RS - 获取标头值的自定义属性

5 java authentication jax-rs

编辑:我刚刚意识到,甚至可以在 Java 中使用自定义属性执行自定义操作吗?或者它只是提供信息?

我想在我的 Jax-RS 服务标头中包含一个身份验证令牌,但我不想向每个请求添加一个参数来获取标头并像这样检查它:

public Response getUser(@Context HttpHeaders headers) {
    if(authorize(headers.getRequestHeader("token").get(0)) {
        // Do something
    }
}
Run Code Online (Sandbox Code Playgroud)

我更愿意为每个请求添加一个属性(如果可能的话,甚至是类:

@Authorize
public Response getUser() {
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

这样我也可以只将属性添加到我想要的请求中。

如果请求未经授权,我可以覆盖它并返回 401。

自定义属性很容易写,但是如何在不每次都传入的情况下获取属性中的头信息呢?

注意:我宁愿不使用 web.xml。我现在没有,我不喜欢使用它们。我想在没有 xml 的情况下保持我的代码干净,我认为如果我使用 filter/web.xml 它将适用于所有调用。如果这是唯一的方法,我会,但我更喜欢具有自定义属性的方法。

Pau*_*tha 2

“我认为如果我使用过滤器/web.xml,它将适用于所有调用”

@NameBinding其实我们可以使用一些注释。例如

@NameBinding
@Rentention(RetentionPoilicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Authorize {}
Run Code Online (Sandbox Code Playgroud)

然后只需注释过滤器和要过滤的方法/类即可。

@Authorize
public Response getUser() {
    // Do something
}

@Provider
@Authorize
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationRequestFilter implements ContainerRequestFilter {

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

        MultivauledMap<String, String> headers - requestContext.getHeaders();
        ...
        if (!authorized) {
            throw new NotAuthorizedException();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意使用@Priority. 这个很重要。假设您还想要进行身份验证,因此您创建了一个用于身份验证的过滤器。如果您不设置优先级,则任一过滤器都可能首先出现。这是不可预测的。如果我们为身份验证过滤器提供@Priority(Priorities.AUTHENTICATION),那么该过滤器将始终出现在@Priority(Priorities.AUTHORIZATION)过滤器之前。

您还需要向子类注册此过滤器Application(请参阅其他一些部署选项(泽西岛,但应用程序子类是可移植的实现)

@ApplicationPath("/api")
public class YourApplication extends Application {
    private Set<Class<?>> classes = new HashSet<>();
    private Set<Object> singletons = new HashSet<>();

    public YourApplication() {
        classes.add(AuthorizationRequestFilter.class);
    }
    @Override
    public Set<Class<?>> getClasses() {
        return classes;
    }
    @Override
    public Set<Object> singletons() {
        return singletons;
    }
}
Run Code Online (Sandbox Code Playgroud)