从 Java Servlet 向 Web API 发送 get 请求

2024-02-09

常见问题

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

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
...
}

Details

我们有使用 TIBCO Spotfire 7.0 作为分析报告引擎的网络应用程序(.NET、MVC5)。 为了允许我们的用户在 Web 应用程序内查看报告,我们使用 Spotfire WebPlayer(IIS Web 应用程序)和 JavaScript API。我们在 Web 应用程序中对用户进行身份验证,然后允许他们利用 JS API 向 WebPlayer 发出请求。为了使用已经经过身份验证的用户,我们根据描述的密钥票在 WebPlayer 上实现了自定义身份验证here http://stn.spotfire.com/stn/Tasks/ImplementingCustomAuthentication.aspx。因此,我们创建了由 Spotfire WebPlayer 加载并调用重写函数的 .NET 程序集。在此函数中,我们调用 Web API 服务来验证用户并获取有效的 Spotfire 用户名,然后我创建IIdentity与收到的用户名。 当新版本的 TIBCO Spotfire 7.5 发布时,我们发现它们removed https://docs.tibco.com/pub/spotfire_server/7.5.0/doc/html/TIB_sfire_server_tsas_admin_help/GUID-03FD5CD2-103C-444B-BE23-B1711C8797A8.html支持自定义身份验证,因为它们changed https://docs.tibco.com/pub/spotfire_server/7.5.0/doc/html/TIB_sfire_server_tsas_admin_help/GUID-24E8A46B-4BB5-4D8C-8F24-FB8D77E8EC63.html架构,现在他们支持“外部认证 https://docs.tibco.com/pub/spotfire_server/7.5.0/doc/html/TIB_sfire_server_tsas_admin_help/GUID-0E4154FC-97AE-43D4-8EBF-A9BD9380D83C.html”。这种方法可以作为 Java servlet 来实现,用于验证用户身份,然后进行 Spotfire:

从 getUserPrincipal() 方法检索用户名 javax.servlet.http.HttpServletRequest

所有这些迫使我们用 Java 重新编写逻辑。然而,我们不想改变身份验证的整体工作流程,并且我们希望坚持已经有效的票务模式。我是 Java servlet 的新手,所以我的目标是基于 servlet 实现相同的身份验证。他们有example https://docs.tibco.com/pub/spotfire_server/7.5.0/doc/api/TIB_sfire_server_Custom_Authentication_Filter_API_Reference/javadoc/index.html其中 servlet 类有方法doGet and doPost (链接到带有示例的 zip https://docs.tibco.com/pub/spotfire_server/7.5.0/doc/api/TIB_sfire_server_Custom_Authentication_Filter_API_Examples.zip)。我在这里的假设是我可以实现我自己的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;   
        }

    }

以及这些初始参数

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 Java Servlet 向 Web API 发送 get 请求 的相关文章

随机推荐