【问题标题】:Java JAX-RS Name Binding Not workingJava JAX-RS 名称绑定不起作用
【发布时间】:2017-06-18 13:33:59
【问题描述】:

我正在为我的 REST 服务开发身份验证过滤器。

谁能解释一下为什么这个名称绑定不起作用。

当我发出 post 请求时,我可以收到字符串“Tokenized”,但日志不打印“Inside the filter”。

import java.io.IOException;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.FormParam;
import javax.ws.rs.NameBinding;
import javax.ws.rs.Produces;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Target;
import javax.annotation.Priority;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;



@Path("/authentication")
public class AuthenticationHandler {

    final static Logger log = Logger.getLogger(AuthenticationHandler.class);

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

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

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

            log.info("Inside the filter");

            // Get the HTTP Authorization header from the request
            String authorizationHeader
                    = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

            // Check if the HTTP Authorization header is present and formatted correctly 
            if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
                throw new NotAuthorizedException("Authorization header must be provided");
            }

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

            try {

                // Validate the token
                validateToken(token);

            } catch (Exception e) {
                requestContext.abortWith(
                        Response.status(Response.Status.UNAUTHORIZED).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
        }


    }

    @POST
    @Secured
    @Path("/request_token")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response authenticateUser(@FormParam("username") String username,
            @FormParam("password") String password) {

        try {

            // Authenticate the user using the credentials provided
            authenticate(username, password);

            // Issue a token for the user
            String token = issueToken(username);

            // Return the token on the response
            return Response.ok(token).build();

        } catch (Exception e) {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }
    }



    private boolean authenticate(String username, String password) throws Exception {
        return true;
    }

    private String issueToken(String username) {
        return "Tokenized";
    }

}

【问题讨论】:

  • 将过滤器放在它自己的文件中,这样它就会被包扫描拾取。它不会被当做内部类。
  • 非常感谢,这解决了我的问题。我正在为任何有同样问题的人发布答案。有没有办法把这些类放在不同的包里,因为我试过了,没用。
  • 您需要修复配置以将带有过滤器的包添加到包扫描中
  • 为了连续性,这是stackoverflow.com/questions/26777083/…的实现

标签: java annotations jersey jetty jax-rs


【解决方案1】:

谢谢你的小费。

在为名称绑定和过滤器创建单独的类后,它现在可以正常工作了。如果有人需要,我将在下面发布解决方案。

我现在的问题是,有没有办法将这两个类保存在一个单独的包中,因为我尝试将它放在我的 Util 包中,但它不能正常工作。

peeskillet:再次感谢您的提示。

AuthenticationFilter.java

import com.binosaurs.sf.backend.handler.Secured;
import com.binosaurs.sf.backend.util.*;
import java.io.IOException;
import javax.annotation.Priority;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;



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

        // Get Log4j Logger
    final static Logger log = Logger.getLogger(AuthenticationFilter.class);

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

            log.info("Inside the filter");

            // Get the HTTP Authorization header from the request
            String authorizationHeader
                    = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

            // Check if the HTTP Authorization header is present and formatted correctly
            if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
                throw new NotAuthorizedException("Authorization header must be provided");
            }

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

            try {

                // Validate the token
                validateToken(token);

            } catch (Exception e) {
                requestContext.abortWith(
                        Response.status(Response.Status.UNAUTHORIZED).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
        }


    }

Secured.java

    /*
    * To change this license header, choose License Headers in Project Properties.
    * To change this template file, choose Tools | Templates
    * and open the template in the editor.
    */
    package com.binosaurs.sf.backend.handler;

    import com.binosaurs.sf.backend.util.*;
    import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.ElementType.TYPE;
    import java.lang.annotation.Retention;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    import java.lang.annotation.Target;
    import javax.ws.rs.NameBinding;

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

AuthenticationHandler.java

    package com.binosaurs.sf.backend.handler;
    import javax.ws.rs.core.Response;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.POST;
    import javax.ws.rs.Path;
    import javax.ws.rs.FormParam;
    import javax.ws.rs.Produces;
    import org.apache.log4j.Logger;



    @Path("/authentication")
    public class AuthenticationHandler {

        final static Logger log = Logger.getLogger(AuthenticationHandler.class);

        @POST
        @Secured
        @Path("/request_token")
        @Produces(MediaType.APPLICATION_JSON)
        @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
        public Response authenticateUser(@FormParam("username") String username,
                @FormParam("password") String password) {

            try {

                // Authenticate the user using the credentials provided
                authenticate(username, password);

                // Issue a token for the user
                String token = issueToken(username);

                // Return the token on the response
                return Response.ok(token).build();

            } catch (Exception e) {
                return Response.status(Response.Status.UNAUTHORIZED).build();
            }
        }



        private boolean authenticate(String username, String password) throws Exception {
            return true;
        }

        private String issueToken(String username) {
            return "Tokenized";
        }

    }

【讨论】:

  • 什么不起作用?当然,您可以将这些类放在单独的包中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 2013-09-28
  • 2013-04-19
相关资源
最近更新 更多