从 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 请求 的相关文章

  • Grails 3.x bootRun 失败

    我正在尝试在 grails 3 1 11 中运行一个项目 但出现错误 失败 构建失败并出现异常 什么地方出了错 任务 bootRun 执行失败 进程 命令 C Program Files Java jdk1 8 0 111 bin java
  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • 列出jshell中所有活动的方法

    是否有任何命令可以打印当前 jshell 会话中所有新创建的方法 类似的东西 list但仅适用于方法 您正在寻找命令 methods all 它会打印所有方法 包括启动 JShell 时添加的方法 以及失败 被覆盖或删除的方法 对于您声明的
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐