12

我们正在尝试将 CAS 服务器用于我们现有的基于 Web 的应用程序的 SSO。我们的目标是

  • 跨各种应用程序(包括跨域)实现 SSO。
  • 当它们被重定向到 CAS 服务器登录页面时,为不同的应用程序定制登录(在 UI 术语中)页面。
  • 无需进入 CAS 登录页面即可登录,原因是页面本身嵌入了“一个小的登录部分”,用户不会被重定向到 CAS 登录页面以获得更好的可用性。

我们完成了第一个和第二个目标。但是第三个有问题。

对于这个功能,我们试图复制与第二个目标相同的操作,唯一的区别是从非 CAS 登录页面提交/发布数据(凭证、登录票等)。

  • 我们不能使用 iframe 在小部分中显示 CAS 登录页面,这容易受到浏览器兼容性问题的影响。
  • 我们不能使用 ajax 来使用 CAS api 获取登录票并进行 HTTP 发布(跨域问题)
  • 我们所做的是:通过在服务器端进行 HTTP 发布,在加载非 CAS 登录页面时检索登录票和执行 ID。当我们发布用户名/密码以及 loginticket 和 execId 时,CAS 服务器不接受发布数据,而是将用户重定向到 CAS 登录页面,但返回浏览器并再次提交数据可以正常工作。原因是 CAS 和浏览器之间没有建立会话,因此 CAS 拒绝任何发布数据。我们可以使用 CAS restAPI,但它只会让用户登录,对完成 SSO 没有帮助。

关于我们如何处理这个问题的任何想法?

谢谢,普拉蒂克

4

4 回答 4

1

有一个关于 CAS 的 wiki 页面对此进行了辩论:https ://wiki.jasig.org/display/CAS/Using+CAS+without+the+Login+Screen (但它比Misagh提出的谷歌小组讨论更早)。

我的解决方案是“从外部链接或自定义外部表单使用 CAS ”。

于 2013-01-11T09:29:42.570 回答
0

我知道为时已晚,但如果有人正在寻找答案,这就是我解决这个问题的方法。这是我放在 casLoginView.jsp 中的代码

<head>
    <script language="javascript">
        function doAutoLogin() {
            document.forms[0].submit();
        }
    </script>
</head>
<body onload="doAutoLogin();">
    <form id="credentials" method="POST" action="<%= request.getContextPath() %>/login?service=<%= request.getParameter("service") %>">
        <input type="hidden" name="lt" value="${loginTicket}" />
        <input type="hidden" name="execution" value="${flowExecutionKey}" />
        <input type="hidden" name="_eventId" value="submit" />
        <input type="hidden" name="serviceLogin" value="<%= request.getParameter("serviceLogin") %>"/>
        <input type="hidden" name="username" value="<%= request.getParameter("username") %>" />
        <input type="hidden" name="password" value="<%= request.getParameter("password") %>" />
        <% 
        if ("true".equals(request.getParameter("rememberMe"))) {%>
            <input type="hidden" name="rememberMe" id="rememberMe" value="true"/>
        <% } %>

        <input type="submit" value="Submit" style="visibility: hidden;" />
    </form>
    <% } else {
        response.sendRedirect(request.getParameter("redirectURL"));
       }
    %>
</body>

在您的 webapp 中,只需向您的 CAS 服务器发出 POST 请求。

希望能帮助到你

于 2015-02-10T14:16:03.513 回答
0

在没有登录屏幕页面的情况下登录 cas,我​​自定义流程登录(编写另一个动作状态)

1.在 login-webflow.xml 中,您可以在 action-state id="generateLoginTicket" 中编写转换的其他动作状态。在这个动作状态(我称之为 submitNotUseForm)中,我执行相同的“realSubmit”动作状态。

2.在评估“submitNotUseForm”-> 类 AuthenticationViaFormAction 时,我编写方法 submitNotForm() 并检查:

2.1:如果没有服务调用,则返回调用“viewLoginForm”的值,否则我从凭据的请求集中获取参数

2.2:其他都做同样的方法提交

它对我有用!

于 2016-09-24T01:03:28.490 回答
0
  1. 您必须获得一份 CAS 官方客户端源代码(cas-client-core,https://github.com/apereo/java-cas-client),并确保您可以编译它。

  2. 您需要更改客户端源代码中 org.jasig.cas.client.authentication.AuthenticationFilter 中的 doFilter() 函数代码,如下所示。

    final HttpServletRequest request = (HttpServletRequest) servletRequest;
    final HttpServletResponse response = (HttpServletResponse) servletResponse;
    final HttpSession session = request.getSession(false);
    final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
    
    if(request.getServletPath().toLowerCase().equals("/caslogout.jsp"))
    {
        // Set the custom client login page when you logout from CAS server.
        request.setAttribute("casServerLogoutUrl",casServerLoginUrl.replace("login","logout"));
        request.setAttribute("customServerLoginUrl",customServerLoginUrl);
    
        //We must remove the attribute of CONST_CAS_ASSERTION manually
        if(session!=null)
            session.removeAttribute(CONST_CAS_ASSERTION);
    
        filterChain.doFilter(request, response);
        return;
    }
    
    if (assertion != null) {
        filterChain.doFilter(request, response);
        return;
    }
    
    // Although the custom login page must called caslogin, here you can change it.
    if(request.getServletPath().toLowerCase().equals("/caslogin.jsp"))
    {
        //Set the a default parameter to the caslogin
        request.setAttribute("defaultServerIndexUrl",defaultServerIndexUrl);
        request.setAttribute("casServerLoginUrl",casServerLoginUrl);
        filterChain.doFilter(request, response);
        return;
    }
    
    final String serviceUrl = constructServiceUrl(request, response);
    final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
    final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
    
    if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
        filterChain.doFilter(request, response);
        return;
    }
    
    final String modifiedServiceUrl;
    
    log.debug("no ticket and no assertion found");
    if (this.gateway) {
        log.debug("setting gateway attribute in session");
        modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
    } else {
        modifiedServiceUrl = serviceUrl;
    }
    
    if (log.isDebugEnabled()) {
        log.debug("Constructed service url: " + modifiedServiceUrl);
    }
    
    final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
    
    if (log.isDebugEnabled()) {
        log.debug("redirecting to \"" + urlToRedirectTo + "\"");
    }
    
    // Add a custom server login url parameter to the CAS login url.
    response.sendRedirect(urlToRedirectTo+"&customLogin=custom&customLoginPage="+customServerLoginUrl);
    
  3. 将自己编译的 cas-client-core 添加到客户端 webapp 的依赖中。

  4. 将 caslogin.jsp 添加到您的客户端 webapp。

     <form method="GET" action="<%=request.getAttribute("casServerLoginUrl")%>">
    <p>Username : <input type="text" name="username" /></p>
    <p>Password : <input type="password" name="password" /></p>
    <p><input type="submit" value="Login" /></p>
    <input type="hidden" name="auto" value="true" />
    <input type="hidden" name="service" value="<%=request.getParameter("service")==null?request.getAttribute("defaultServerIndexUrl"):request.getParameter("service")%>" />

  1. 在客户端 webapp 中编辑 web.xml。在 CASFilter 的过滤器中添加以下代码

<init-param>
    <param-name>defaultServerIndexUrl</param-name>
    <param-value>http://clientip:port/webappname/index.jsp</param-value>
</init-param>
<init-param>
    <param-name>customServerLoginUrl</param-name>
    <param-value>http://clientip:port/webappname/caslogin.jsp</param-value>
</init-param>

  1. 在 CAS 服务器 Web 应用程序中编辑 cas-server-webapp/WEB-INF/view/jsp/default/ui/casLoginView.jsp 中的代码。

<%
  String auto=request.getParameter("auto");
  String customLogin=request.getParameter("customLogin");

  if(auto!=null&&auto.equals("true"))
  {
    %>
    <html>
    <head>
      <script language="javascript">
        function doAutoLogin()
        {
          document.forms[0].submit();
        }
      </script>
    </head>
    <body onload="doAutoLogin()">
    <form id="credentials" method="POST" action="<%=request.getContextPath()%>/login?service=<%=request.getParameter("service")%>">
      <input type="hidden" name="lt" value="${loginTicket}" />
      <input type="hidden" name="execution" value="${flowExecutionKey}" />
      <input type="hidden" name="_eventId" value="submit" />
      <input type="hidden" name="username" value="<%=request.getParameter("username")%>" />
      <input type="hidden" name="password" value="<%=request.getParameter("password")%>" />
      <input type="hidden" name="login_form" value="<%=request.getParameter("login_form")%>" />
      <input type="hidden" name="rememberMe" value="true" />
      <input type="submit" value="Submit" style="visibility: hidden" />
    </form>
    </body>
    </html>

    <%
}
else if(customLogin!=null&&customLogin.equals("custom"))
{  
  response.sendRedirect(request.getParameter("customLoginPage")+"?service="+request.getParameter("service"));
%>
<%
}
else
{%>
<!-- The Orgin Source Code of casLoginView.jsp!!!!!!!!!!!!!!!!!!!!!!!!! -->
<%}%>

  1. 确保您可以使用 caslogin.jsp 登录 cas。
  2. 将自己登录页面的内容放到 caslogin.jsp 中。
  3. 现在您可以使用自己的 caslogin.jsp 登录 cas

我还制作了一个关于如何使用客户端自定义登录屏幕而不是服务器登录屏幕登录 cas 的示例。您可以在https://github.com/yangminxing/cas-custom-login-page上下载它

于 2016-08-15T08:17:57.263 回答