java - JAX-RS 身份验证过滤器不是通过@Secured 注释触发的

标签 java rest web-services authentication jax-rs

我正在关注这个答案:Best practice for REST token-based authentication with JAX-RS and Jersey实现 REST API 身份验证。但是 JAX-RS 身份验证过滤器不是通过 @Secured 注释触发的。

我通过在方法上添加 @Secured 完成了保护您的 REST 端点部分。

我就是这样做的。

安全.java

@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Secured { }

AuthenticationFilter.java

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

    private static final String AUTHENTICATION_SCHEME = "Bearer";

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        // Get the Authorization header from the request
        String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

        // Validate the Authorization header
        if (!isTokenBasedAuthentication(authorizationHeader)) {
            abortWithUnauthorized(requestContext);
            return;
        }

        // Extract the token from the Authorization header
        String token = authorizationHeader.substring(AUTHENTICATION_SCHEME.length()).trim();

        try {
            validateToken(token);
        } catch (Exception e) {
            abortWithUnauthorized(requestContext);
        }
    }

    private boolean isTokenBasedAuthentication(String authorizationHeader) {
        // Check if the Authorization header is valid
        // It must not be null and must be prefixed with "Bearer" plus a whitespace
        // Authentication scheme comparison must be case-insensitive
        return (authorizationHeader != null &&
            authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " "));
    }

    private void abortWithUnauthorized(ContainerRequestContext requestContext) {
        // Abort the filter chain with a 401 status code
        // The "WWW-Authenticate" is sent along with the response
        requestContext.abortWith(
                Response.status(Response.Status.UNAUTHORIZED)
                    .header(HttpHeaders.WWW_AUTHENTICATE, AUTHENTICATION_SCHEME)
                    .build());
    }

    private void validateToken(String token) throws Exception {
        // Check if it was issued by the server and if it's not expired
        // Throw an Exception if the token is invalid
    }

MyApis.java

@Path("api")
public class MyApis {

    @GET
    @Secured
    @Path("me")
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String, X500Name> whoAmI() {
        return ImmutableMap.of("me", legalName);
    }

    // other APIs
}

当我调用/api/me 时,我可以直接得到响应而无需提供任何身份验证 header 。过滤器似乎未触发或未正确注册。

我看过这个问题JAX RS, my filter is not working ,但这并没有解决我的问题。

我如何理解以下内容是不需要 web.xml 对吧?

This solution uses only the JAX-RS 2.0 API, avoiding any vendor specific solution. So, it should work with the most popular JAX-RS 2.0 implementations, such as Jersey, RESTEasy and Apache CXF.

It's important mention that if you are using a token-based authentication, you are not relying on the standard Java EE web application security mechanisms offered by the servlet container and configurable via application's web.xml descriptor.

最佳答案

回答晚了,但这个问题的解决方案是将 AuthenticationFilter 添加到您的类中。

public class App extends Application { @Override public Set<Class<?>> getClasses() { final Set<Class<?>> classes = new HashSet<>(); classes.add(MyApis.class); classes.add(AuthenticationFilter.class); return classes; } }

关于java - JAX-RS 身份验证过滤器不是通过@Secured 注释触发的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45802390/

相关文章:

c# - 如何获取内容类型

java - 使用其他类的数组列表和适配器

java - 即使安装了 netbeans 7.2(完整包),我是否还需要安装 Java EE6 SDK?

java - 如何知道 CompletionService 何时完成交付结果?

java - Hamcrest 匹配器 closeTo 无法按预期工作

c# - 在 OWIN 身份验证期间获取路由属性?

java - Swing 中的 JTable

.net - RESTful WCF 的最低配置

c# - 具有分页、排序和过滤功能的 WebAPI Get 方法

javascript - 如何在jquery html应用程序中使用wcf服务作为远程或本地?