title: JAX-RS Authentication Filter is not triggered via @Secured annotation
body: <p>I am following this answer: <a href="https://stackoverflow.com/a/26778123/4802797">Best practice for REST token-based authentication with JAX-RS and Jersey</a> to implement the REST API authentication.   But the JAX-RS Authentication Filter is not triggered via @Secured annotation.</p>
  
  <p>I finished until the part <strong>Securing your REST endpoints</strong> by adding <code>@Secured</code> on the method.</p>
  
  <p>This is how I am doing this.</p>
  
  <h2>Secured.java</h2>
  
  <pre><code>@NameBinding
  @Retention(RUNTIME)
  @Target({TYPE, METHOD})
  public @interface Secured { }
  </code></pre>
  
  <h2>AuthenticationFilter.java</h2>
  
  <pre><code>@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 &amp;&amp;
              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
      }
  </code></pre>
  
  <h2>MyApis.java</h2>
  
  <pre><code>@Path("api")
  public class MyApis {
  
      @GET
      @Secured
      @Path("me")
      @Produces(MediaType.APPLICATION_JSON)
      public Map&lt;String, X500Name&gt; whoAmI() {
          return ImmutableMap.of("me", legalName);
      }
  
      // other APIs
  }
  </code></pre>
  
  <p>When I call <code>/api/me</code>, I can get the response directly without any authentication header provided.   It seems like the filter is not triggered or not registered properly.   </p>
  
  <p>I have seen this question <a href="https://stackoverflow.com/questions/38679654/jax-rs-my-filter-is-not-working">JAX RS, my filter is not working</a>, but it does not solve my problem.</p>
  
  <p>And how I understand the following is that <code>web.xml</code> is not needed right?</p>
  
  <blockquote>
    <p>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.</p>
    
    <p>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.</p>
  </blockquote>