【问题标题】:CAS: Invoking a webservice programmatically from within a servletCAS:从 servlet 中以编程方式调用 Web 服务
【发布时间】:2015-02-18 12:50:04
【问题描述】:

我有两个应用程序在 2 个不同的服务器上运行(一个在 tomcat 上,另一个在 JBoss 上)。这两个应用程序都连接到同一个 CAS 服务器进行身份验证。现在这个 CAS 服务器也驻留在同一个 JBoss 中。

Say:
App-1 --- is on tomcat and CASified
App-2 --- is on JBoss and CASified
CAS   --- is on JBoss

现在我正在从浏览器调用 App-1 的 URL。出现 CAS 登录页面,提供用户名/密码后,请求现在成功进入 App-1 的 servlet。从这个 servlet 代码中,我试图调用驻留在 App-2 中的 Web 服务。

Note: I use axis2 for this webservice and the axis2.war is also CASified
      to the same CAS server for authentication.

无论我做什么,我都无法使这个 web 服务调用工作。有没有办法做到这一点?

Note: If I call the CAS REST api with a hardcoded username/password, I am 
getting the TGT, through which I am able to get the Service Ticket, with 
which I am able to invoke that web-service. But I do not want to login again 
with a hard-coded username or password. My webservice invocation should 
happen with the already logged-in user only. 

【问题讨论】:

    标签: java web-services servlets cas


    【解决方案1】:

    当您在 App-2 上调用 Web 服务时,您是否获得了会话 cookie?这应该是您无需在每次调用中重新进行身份验证即可继续访问的机制。如果您没有取回 cookie,那么在每次不进行身份验证的情况下就无法继续访问(即服务器无法记住是您本人并且它应该信任消息的其余部分)。

    【讨论】:

    • 感谢您的回复。对我的网络服务调用的响应是 CAS 登录页面,我被困在那里。
    • 对不起,我误解了——当您调用 WebService 并拖着服务票证调用它时,我以为它正在工作?如果是这样,我想知道该服务是否也在其响应中返回了烹饪?如果没有,问题的代码 sn-p 可能会有所帮助。
    • CAS 提供 REST 服务以获取 TGT 并随后从中获取服务票证。从 servlet 内部,我以编程方式调用它们来获取 TGT(使用硬编码的用户名和密码)和服务票证。之后,我将服务票证附加到 web 服务 url 并成功调用它。 - 这就是我在问题的最后一个“注释”中试图解释的内容。
    • 好的,好的,我明白了!那么,我的问题可以追溯到/当 Web 服务成功返回时/,它(或容器)是否将会话 cookie 作为响应的一部分发回?通常 CASified 应用程序会这样做,从而产生一个会话 cookie(JSESSIONID 等),该会话 cookie 可用作访问服务的后续请求的一部分。
    • 我正在使用 axis2 客户端 API 进行 Web 服务调用。所以我不确定它是否会返回。它可能会回来,我没有深入研究它。但我想要的是,该 Web 服务调用本身应该与当前的 SSO 会话(即当前的 servlet)一起工作,而无需重新登录 CAS。
    【解决方案2】:

    这可以通过使用 CAS 代理功能来实现。 链接 https://wiki.jasig.org/display/CAS/Proxy+CAS+Walkthrough 有点帮助。但无法理解从哪里开始。 首先从 http://downloads.jasig.org/cas-clients/ 获取 CAS 客户端 jar。就我而言,我拿了cas-client-core-3.3.3.jar jar。我已将这个 jar 包含在我的应用程序战争中。 在我的应用程序的 web.xml 中,我包含了以下 3 个 CAS 过滤器。

    <!-- CAS Filters -->
    <filter>
        <filter-name>CAS Validation Filter</filter-name>
        <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
        <init-param>
            <param-name>casServerUrlPrefix</param-name>
            <param-value>https://cas-hostname.domainname:port/cas</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>https://app-hostname.domainname:port</param-value>
        </init-param>
        <init-param>
            <param-name>proxyCallbackUrl</param-name>
            <param-value>https://app-hostname.domainname:port/app/ticket</param-value>
        </init-param>
        <init-param>
            <param-name>proxyReceptorUrl</param-name>
            <param-value>/app/ticket</param-value>
        </init-param>
    </filter>
    
    
    <filter>
        <filter-name>CAS Authentication Filter</filter-name>
        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
        <init-param>
            <param-name>casServerLoginUrl</param-name>
            <param-value>https://cas-hostname.domainname:port/cas/login</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>https://app-hostname.domainname:port</param-value>
        </init-param>
    </filter>
    
    
    <filter>
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
        <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
    </filter>
    
      <!-- filter mappings -->
    <filter-mapping>
        <filter-name>CAS Validation Filter</filter-name>
        <url-pattern>/app/*</url-pattern>
        <url-pattern>/ticket</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
        <filter-name>CAS Authentication Filter</filter-name>
        <url-pattern>/app/*</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
        <url-pattern>/app/*</url-pattern>
    </filter-mapping>
    

    注1:过滤器映射的顺序应该如上所述。 第一个CAS Validation filter mapping应该来了,后面是CAS 身份验证过滤器和最后一个 CAS HttpServletRequest Wrapper 过滤器。

    注 2:URL 模式 /ticket 基本上是您的代理回调 最后两个过滤器中不需要提及 url。

    一旦 CAS 客户端 jar 包含在使用这些过滤器配置的 web-app 和 web.xml 中,那么所有 http 请求都会通过这些过滤器。

    所以一旦你的http请求进入你的servlet,那么你就可以调用下面的代码sn-p来获取代理票:

    String proxyTicket = ((AttributePrincipal) req.getUserPrincipal())
                    .getProxyTicketFor(webservice_url);
    

    req 是 HttpServletRequest 对象,AttributePrincipal 是存在于 cas-client-core-3.3.3.jar 中的类

    然后可以将此 proxyTicket 作为查询字符串附加到您的 Web 服务的 URL,如下所示:

    https://myother-webservice-app.com/ws/myData?ticket=<proxyTicket>
    

    构建此 URL 后,您可以通过编程方式调用 Web 服务。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多