JASIG CAS Вход без экрана входа в систему CAS
Мы пытаемся использовать сервер CAS для единого входа для наших существующих веб-приложений. Наши цели
- Добейтесь единого входа в различных приложениях (включая междоменные).
- Иметь настраиваемые страницы входа (в терминах пользовательского интерфейса) для разных приложений, когда они перенаправляются на страницу входа в CAS Server.
- Возможность входа в систему без перехода на страницу входа в CAS, причина в том, что "небольшая секция входа в систему" встроена в саму страницу, и пользователь не будет перенаправлен на страницу входа в CAS для удобства использования.
Мы сделали с первой и второй целью. Но возникли проблемы с третьим.
Для этой функциональности мы пытаемся повторить те же действия, что и во второй цели, с той лишь разницей, что отправка / публикация данных (учетные данные, входные билеты и т. Д.) Со страницы входа не в CAS.
- Мы не можем использовать iframes для отображения страницы входа в CAS в небольшом разделе, это уязвимо для проблем совместимости браузера.
- Мы не можем использовать ajax, чтобы использовать API-интерфейсы CAS для получения билета на вход и выполнения HTTP-сообщения (междоменная проблема)
- То, что мы сделали, это: Извлеките login ticket и id выполнения при загрузке не входящей в систему страницы входа в систему, выполнив HTTP-сообщение на стороне сервера. Когда мы публикуем имя пользователя / пароль вместе с login ticket и execId, сервер CAS вместо того, чтобы принимать данные публикации, перенаправляет пользователя на страницу входа в CAS, но возвращает браузер и снова отправляет данные. Причины не установлены между CAS и браузером, и поэтому CAS отклоняет любые данные поста. Мы можем использовать restAPI CAS, но он просто войдет в систему пользователя и не поможет в создании единого входа.
Есть мысли о том, как мы можем справиться с этой проблемой?
Спасибо пратик
5 ответов
Вы должны получить копию официального исходного кода клиента CAS (cas-client-core, https://github.com/apereo/java-cas-client) и убедиться, что вы можете скомпилировать его.
Вам необходимо изменить код функции doFilter() по адресу org.jasig.cas.client.authentication.AuthenticationFilter в исходном коде клиента, как показано ниже.
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);
Добавьте свое собственное скомпилированное cas-client-core к зависимости вашего клиентского веб-приложения.
Добавьте caslogin.jsp в ваше клиентское веб-приложение.
<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")%>" />
- Отредактируйте файл 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>
- Отредактируйте код в cas-server-webapp/WEB-INF/view/jsp/default/ui/casLoginView.jsp в веб-приложении сервера CAS.
<%
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!!!!!!!!!!!!!!!!!!!!!!!!! -->
<%}%>
- УБЕДИТЕСЬ, что вы можете войти в систему с помощью caslogin.jsp.
- Поместите содержимое вашей собственной страницы входа в caslogin.jsp.
- Теперь вы можете войти в систему с вашим собственным caslogin.jsp
Я также делаю пример того, как войти в систему с помощью пользовательского экрана входа клиента, а не с сервера входа в систему srceen. Вы можете скачать его на
https://github.com/yangminxing/cas-custom-login-page
На CAS есть вики-страница, которая обсуждает это: https://wiki.jasig.org/display/CAS/Using+CAS+without+the+Login+Screen (но она старше, чем обсуждение групп Google, предложенное Misagh Moayyed)
Мое решение " Использование CAS из внешней ссылки или пользовательской внешней формы".
мы попытались подключиться к CAS и добавить &gateway=true в параметр URL. CAS будет перенаправлять на base_url/j_spring_cas_security_check нашего приложения, не отображая приглашение для входа в систему (наше приложение использовало Spring с CAS)
Чтобы войти в систему без страницы входа в систему, я настраиваю поток входа в систему (напишите другое действие-состояние)
1. В login-webflow.xml вы пишете другое action-состояние перехода в action-state id="generateLoginTicket". В этом action-состоянии (я называю это submitNotUseForm) я делаю то же самое "realSubmit" action-состояние.
2. Оценивая "submitNotUseForm" -> class AuthenticationViaFormAction, я пишу метод submitNotForm() и проверяю:
2.1: если нет вызова службы, он возвращает значение для вызова "viewLoginForm", иначе я получаю параметр из набора запросов для учетных данных
2.2: Все остальное сделать таким же методом отправки
Это работает для меня!
Я знаю, что уже поздно, но если кто-то ищет ответ, я так решаю. Это код, который я положил в 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>
А в вашем веб-приложении просто сделайте POST-петицию на ваш сервер CAS.
Надеюсь, поможет