簡體   English   中英

沒有 CAS 登錄屏幕的 JASIG CAS 登錄

[英]JASIG CAS Login without CAS login screen

我們正在嘗試將 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 沒有幫助。

關於我們如何處理這個問題的任何想法?

謝謝,普拉蒂克

有一個關於 CAS 的 wiki 頁面對此進行了辯論: https ://wiki.jasig.org/display/CAS/Using+CAS+without+the+Login+Screen (但它比Misagh提出的谷歌小組討論更早)。

我的解決方案是“ 從外部鏈接或自定義外部表單使用 CAS ”。

我知道為時已晚,但如果有人正在尋找答案,這就是我解決這個問題的方法。 這是我放在 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 請求。

希望能幫助到你

  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

在沒有登錄屏幕頁面的情況下登錄 cas,我​​自定義流程登錄(編寫另一個動作狀態)

1.在 login-webflow.xml 中,您可以在 action-state id="generateLoginTicket" 中編寫轉換的其他動作狀態。 在這個動作狀態(我稱之為 submitNotUseForm)中,我執行相同的“realSubmit”動作狀態。

2.在評估“submitNotUseForm”-> 類 AuthenticationViaFormAction 時,我編寫方法 submitNotForm() 並檢查:

2.1:如果沒有服務調用,則返回調用“viewLoginForm”的值,否則我從憑據的請求集中獲取參數

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

它對我有用!

我們嘗試點擊 CAS 並在 URL 參數中添加 &gateway=true。 CAS 將重定向到我們應用程序的 base_url/j_spring_cas_security_check 而不顯示登錄提示(我們的應用程序使用帶有 CAS 的 Spring)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM