java - 从 Java Servlet 向 Web API 发送 get 请求

标签 java servlets asp.net-web-api2 servlet-filters spotfire

常见问题

是否可以从 Java servlet 的 doGet 方法发送 get 请求?我需要针对我的 Web API .NET 服务检查一些“票据”,那么我可以在 doGet 方法中从我的自定义 Servlet 调用此服务吗?

public class IdentityProviderServlet extends HttpServlet {
...
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
...
// make request to Web API and save received user name to response
...
}

详细信息

我们有使用 TIBCO Spotfire 7.0 作为分析报告引擎的网络应用程序(.NET、MVC5)。 为了允许我们的用户在 Web 应用程序内查看报告,我们使用 Spotfire WebPlayer(IIS Web 应用程序)和 JavaScript API。我们在 Web 应用程序中对用户进行身份验证,然后允许他们利用 JS API 向 WebPlayer 发出请求。为了使用已经经过身份验证的用户,我们根据 key 票证在 WebPlayer 上实现了自定义身份验证,如 here 中所述。 。因此,我们创建了由 Spotfire WebPlayer 加载并调用重写函数的 .NET 程序集。在此函数中,我们调用 Web API 服务来验证用户并获取有效的 Spotfire 用户名,然后我使用收到的用户名创建 IIdentity。 当新版本的 TIBCO Spotfire 7.5 发布时,我们发现它们 removed支持自定义身份验证,因为它们changed架构,现在他们支持“external authentication ”。这种方法可以作为 Java servlet 来实现,用于验证用户身份,然后进行 Spotfire:

Retrieves the user name from the getUserPrincipal() method of javax.servlet.http.HttpServletRequest

所有这些迫使我们用 Java 重新编写逻辑。然而,我们不想改变身份验证的整体工作流程,并且我们希望坚持已经有效的票务模式。我是 Java servlet 的新手,所以我的目标是基于 servlet 实现相同的身份验证。他们有example其中 servlet 类具有方法 doGetdoPost ( link to zip with example )。我在这里假设我可以实现自己的 doGet 并向 Web API 发送请求以验证票证并取回用户名。

有意义吗?

最佳答案

最后我得到了这段代码。我实现了简单的过滤器而不是 servlet。

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import java.io.*;
import org.json.*;

public class Authenticator implements IAuthenticator {

    @Override
    public IIdentity doAuthentication(String pathToAuthIdentity) throws IOException {
        try {
            // Create an instance of HttpClient.
            HttpClient httpClient = HttpClients.createDefault();

            // Create a method instance.
            HttpGet get = new HttpGet(pathToAuthIdentity);

            HttpResponse response = httpClient.execute(get);

            int internResponseStatus = response.getStatusLine().getStatusCode();

            if(200 == internResponseStatus)
            {
                BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

                StringBuffer result = new StringBuffer();
                String line = "";
                while ((line = rd.readLine()) != null) {
                    result.append(line);
                }

                String userName = null;
                try {
                    JSONObject obj = new JSONObject(result.toString());
                    userName = obj.getString("SpotfireUser");
                } catch (JSONException ex) {
                }
                return new Identity(userName);                
            }else
            {
                return new AIdentity(null);                
            }

        } catch (IOException ex) {
            throw ex;
        } 
    }

    public class AIdentity implements IIdentity
    {
        private final String UserName;
        public AIdentity(String userName)
        {
            this.UserName = userName;
        }
        @Override
        public String getName() {
            return UserName;
        }

    }
}

这就是我使用这个类的方式

    import java.io.IOException;
    import java.security.Principal;
    import javax.servlet.http.*;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;


    public class SpotfireAuthFilter implements Filter {

        private static final String AUTHENTICATION_SERVICE_URL_PARAM = "AUTHENTICATION_SERVICE_URL";
        private static final String COOKIE_NAME_PARAM = "COOKIE_NAME";



        private ServletContext context;    
        private String[] SpotfireTicketNames = null;
        private String[] AuthServiceBaseURLs = null;

        private IAuthenticator AuthService;

        @Override
        public void init(FilterConfig fc) throws ServletException {
            context = fc.getServletContext();

            if(null == fc.getInitParameter(AUTHENTICATION_SERVICE_URL_PARAM) 
                || null == fc.getInitParameter(COOKIE_NAME_PARAM) )
            {
                throw new ServletException("Can't read filter initial parameters");
            }

            AuthServiceBaseURLs = fc.getInitParameter(AUTHENTICATION_SERVICE_URL_PARAM).split(",");
            SpotfireTicketNames = fc.getInitParameter(COOKIE_NAME_PARAM).split(",");
            AuthService = new Authenticator();

            if(SpotfireTicketNames.length != AuthServiceBaseURLs.length)
            {
                throw new ServletException(
                        String.format("Count of '%s' parameter don't equal '%s' parameter", 
                                COOKIE_NAME_PARAM, 
                                AUTHENTICATION_SERVICE_URL_PARAM));
            }

        }

        @Override
        public final void doFilter(
                ServletRequest servletRequest,
                ServletResponse servletResponse,
                FilterChain chain)  throws ServletException 
        {
            final HttpServletRequest request = (HttpServletRequest) servletRequest;
            final HttpServletResponse response = (HttpServletResponse) servletResponse;

            try 
            {
                doFilter(request, response, chain);
            } 
            catch (IOException | RuntimeException e) 
            {
              // Not possible to authenticate, return a 401 Unauthorized status code without any WWW-Authenticate header

              sendError(response, 401, "Unauthorized");
            }
        }

        @Override
        public void destroy() {
         // do nothing   
        }

        private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException 
        {

            String url = getAuthServiceURL(request);
            if(null != url)           
            {


                IIdentity identity = AuthService.doAuthentication(url);
                if(null != identity)
                {
                    String userName = identity.getName();
                    if(null != userName && !userName.equalsIgnoreCase(""))
                    {
                        Principal principal = createPrincipal(userName);

                        // Pass on the request to the filter chain and the authentication framework
                        // should pick up this priincipal and authenticate user
                        chain.doFilter(new WrappedHttpServletRequest(request, principal), response);


                    }
                    else
                    {
                        throw new IOException("Authentication failed");
                    }
                }else
                {
                    throw new IOException("Can't authenticate user by url " + url);
                }
            }
            else
            {
                throw new IOException("Can't find ticket to authenticate user.");
            }

            // Done!
            return;
        }

        private void sendError(HttpServletResponse response, int statusCode, String message) {
            try {
              response.sendError(statusCode, message);
            } catch (IOException e) {

            }
        }

        private String getAuthServiceURL(HttpServletRequest request) {

            Cookie[] cookies  = request.getCookies();
            for(int i =0; i< cookies.length; ++i)
            {
                for(int j =0; j< SpotfireTicketNames.length; ++j)
                {
                    if(cookies[i].getName().equalsIgnoreCase(SpotfireTicketNames[j]))
                    {
                        return String.format(AuthServiceBaseURLs[j], cookies[i].getValue());
                    }    
                }
            }
            return null;
        }


    private Principal createPrincipal(String username) 
    {

        // check does username contain domain/email/display name 
        return new APrincipal(username);
    }



    /**
     * A wrapper for {@link HttpServletRequest} objects.
     */
    private static class WrappedHttpServletRequest extends HttpServletRequestWrapper {

      private final Principal principal;

      public WrappedHttpServletRequest(HttpServletRequest request, Principal principal) {
        super(request);
        this.principal = principal;
      }

      @Override
      public Principal getUserPrincipal() {
        return this.principal;
      }

    } // WrappedHttpServletRequest
  }


    public class APrincipal implements Principal {
        private final String _username;

        public APrincipal(String username) {
           _username = username;
        }

        @Override
        public String getName() {
         return _username;   
        }

    }

以及这些初始参数

initial parameters

关于java - 从 Java Servlet 向 Web API 发送 get 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36077981/

相关文章:

java - getRequestDispatcher() 到另一个上下文

c# - 多个 REST API 方法可以共享同一个 Controller 类吗?

c# - 具有路由属性的模糊 Controller 名称 : controllers with same name and different namespace for versioning

java - 如何在 Mac OS X 上安装 mod_jk

java - 根据输入字符串解析 LocalDateTime

java - 在 @AfterMethod 中的 TestNG 中,我如何知道测试结果?

java - Apache Camel : request-reply pattern with bean URIs and async-http-client

java - servlet 登录站点后不重定向页面,在网络中,仪表板文件的状态代码超过 200,但没有重定向

java - GWT 远程日志记录无法记录 Throwable Stacktrace?

c# - 如何在 C# web api 中的查询字符串上绑定(bind) guid 列表?