【问题标题】:Access servlet annotations from filter从过滤器访问 servlet 注释
【发布时间】:2017-08-08 07:03:05
【问题描述】:

我需要一个在每个 servlet 之前调用的过滤器,并检查该 servlet 是否有说明它需要身份验证的注释,例如 Servlet 3 中的 @ServletSecurity(@HttpConstraint(rolesAllowed={"user"}))。如果不是这种情况,则过滤器将返回。如果 servlet 需要身份验证,它将检查请求令牌是否具有 user 角色,如果没有,它将自动设置一个 NOT_AUTHENTICATED 响应,甚至不通过 servlet。

这项工作必须由过滤器完成,因为我需要验证请求中的 JWT 令牌并将解码的 JWT 添加到请求中,以便 servlet 可以使用它的有效负载。

如何检查过滤器中的 servlet 注释?在这种情况下,我可以在 servlet 中创建一个更简单的注释,例如 @RequiresAuth 吗?因为我不需要这个项目中的角色。

是否可以在不通过 servlet 的情况下从过滤器向客户端返回未经身份验证的响应?

是否可以通过编程将过滤器设置为第一个?

这就是我使用 Jersey 解决它的方法,但我需要一个仅使用 servlet 的解决方案:

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

    @Context
    private ResourceInfo resourceInfo;

    @Override
    public void filter(ContainerRequestContext context) {
        final Method method = resourceInfo.getResourceMethod();

        if (method.isAnnotationPresent(PermitAll.class)) return;
        if (method.isAnnotationPresent(DenyAll.class)) {
            context.abortWith(Response.status(Response.Status.FORBIDDEN).build());
            return;
        }

        final RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
        if (rolesAnnotation == null) return;
    }
}

【问题讨论】:

    标签: java servlets jakarta-ee


    【解决方案1】:

    如何检查过滤器中的 servlet 注释?在这种情况下,我可以在 servlet 中创建一个更简单的注释,例如 @RequiresAuth 吗?因为我不需要这个项目中的角色。

    这是可能的,但不建议这样做。过滤器旨在选择性地应用于需要它们的 servlet。在您的情况下,我只会将其映射到那些需要身份验证的 servlet。

    在您的 Jersey 示例中,AuthenticationFilter 适用于所有端点。使用 servlet 过滤器,您可以决定希望此过滤器应用于哪些 servlet/url 模式。在这里自省注释不再有意义。

    是否可以在不通过 servlet 的情况下从过滤器向客户端返回未经身份验证的响应?

    是的。您通过调用 response.setStatus(401) 而不是 chain.doFilter 从过滤器返回。

    if (isAuthenticated()) {
        // this proceeds to the next filter or servlet in the chain
        chain.doFilter(request, response);
    }
    else {
        // this returns the response to the client
        response.setStatus(401);
    }
    

    是否可以通过编程将过滤器设置为第一个?

    是的。无法通过注解实现,但可以通过 web.xml 实现。这只是任何给定 servlet 或 url-pattern 的元素顺序。

    <filter>
        <filter-name>filter1</filter-name>
        <filter-class>filter.Filter1</filter-class>
    </filter>
    
    <filter>
        <filter-name>filter2</filter-name>
        <filter-class>filter.Filter2</filter-class>
    </filter>
        
    <!-- filter2 will be applied 1st because it's listed 1st -->
    <filter-mapping>
        <filter-name>filter2</filter-name>
        <servlet-name>some-servlet</servlet-name>
    </filter-mapping>
    
    <!-- filter1 will be applied after filter2 -->
    <filter-mapping>
        <filter-name>filter1</filter-name>
        <servlet-name>some-servlet</servlet-name>
    </filter-mapping>
    

    【讨论】:

      猜你喜欢
      • 2010-11-26
      • 2011-01-25
      • 1970-01-01
      • 2013-02-23
      • 2014-03-20
      • 2011-12-30
      • 2011-04-14
      • 2013-10-22
      • 2015-04-07
      相关资源
      最近更新 更多