客户端篇:
1.替换原来过滤器org.jasig.cas.client.authentication.AuthenticationFilter,改成自己的过滤器RemoteAuthenticationFilter.java,这个过滤器可以自己随便放到哪个包中,保证web.xml能够正确引用到就行:
- public class RemoteAuthenticationFilter extends AbstractCasFilter
- {
- public static final String CONST_CAS_GATEWAY = "_const_cas_gateway_";
- /**
- * 本地登陆页面URL.
- */
- private String localLoginUrl;
- /**
- * The URL to the CAS Server login.
- */
- private String casServerLoginUrl;
- /**
- * Whether to send the renew request or not.
- */
- private boolean renew = false;
- /**
- * Whether to send the gateway request or not.
- */
- private boolean gateway = false;
- protected void initInternal(final FilterConfig filterConfig)
- throws ServletException
- {
- super.initInternal(filterConfig);
- setCasServerLoginUrl(getPropertyFromInitParams(filterConfig,
- "casServerLoginUrl", null));
- log.trace("Loaded CasServerLoginUrl parameter: "
- + this.casServerLoginUrl);
- setLocalLoginUrl(getPropertyFromInitParams(filterConfig,
- "localLoginUrl", null));
- log.trace("Loaded LocalLoginUrl parameter: " + this.localLoginUrl);
- setRenew(Boolean.parseBoolean(getPropertyFromInitParams(filterConfig,
- "renew", "false")));
- log.trace("Loaded renew parameter: " + this.renew);
- setGateway(Boolean.parseBoolean(getPropertyFromInitParams(filterConfig,
- "gateway", "false")));
- log.trace("Loaded gateway parameter: " + this.gateway);
- }
- public void init()
- {
- super.init();
- CommonUtils.assertNotNull(this.localLoginUrl,
- "localLoginUrl cannot be null.");
- CommonUtils.assertNotNull(this.casServerLoginUrl,
- "casServerLoginUrl cannot be null.");
- }
- public final void doFilter(final ServletRequest servletRequest,
- final ServletResponse servletResponse, final FilterChain filterChain)
- throws IOException, ServletException
- {
- final HttpServletRequest request = (HttpServletRequest) servletRequest;
- final HttpServletResponse response = (HttpServletResponse) servletResponse;
- final HttpSession session = request.getSession(false);
- final String ticket = request.getParameter(getArtifactParameterName());
- final Assertion assertion = session != null ? (Assertion) session
- .getAttribute(CONST_CAS_ASSERTION) : null;
- final boolean wasGatewayed = session != null
- && session.getAttribute(CONST_CAS_GATEWAY) != null;
- // 如果访问路径为localLoginUrl且带有validated参数则跳过
- URL url = new URL(localLoginUrl);
- final boolean isValidatedLocalLoginUrl = request.getRequestURI()
- .endsWith(url.getPath())
- && CommonUtils.isNotBlank(request.getParameter("validated"));
- if (!isValidatedLocalLoginUrl && CommonUtils.isBlank(ticket)
- && assertion == null && !wasGatewayed)
- {
- log.debug("no ticket and no assertion found");
- if (this.gateway)
- {
- log.debug("setting gateway attribute in session");
- request.getSession(true).setAttribute(CONST_CAS_GATEWAY, "yes");
- }
- final String serviceUrl = constructServiceUrl(request, response);
- if (log.isDebugEnabled())
- {
- log.debug("Constructed service url: " + serviceUrl);
- }
- String urlToRedirectTo = CommonUtils.constructRedirectUrl(
- this.casServerLoginUrl, getServiceParameterName(),
- serviceUrl, this.renew, this.gateway);
- // 加入localLoginUrl
- urlToRedirectTo += (urlToRedirectTo.contains("?") ? "&" : "?")
- + "loginUrl=" + URLEncoder.encode(localLoginUrl, "utf-8");
- if (log.isDebugEnabled())
- {
- log.debug("redirecting to \"" + urlToRedirectTo + "\"");
- }
- response.sendRedirect(urlToRedirectTo);
- return;
- }
- if (session != null)
- {
- log.debug("removing gateway attribute from session");
- session.setAttribute(CONST_CAS_GATEWAY, null);
- }
- filterChain.doFilter(request, response);
- }
- public final void setRenew(final boolean renew)
- {
- this.renew = renew;
- }
- public final void setGateway(final boolean gateway)
- {
- this.gateway = gateway;
- }
- public final void setCasServerLoginUrl(final String casServerLoginUrl)
- {
- this.casServerLoginUrl = casServerLoginUrl;
- }
- public final void setLocalLoginUrl(String localLoginUrl)
- {
- this.localLoginUrl = localLoginUrl;
- }
- }
public class RemoteAuthenticationFilter extends AbstractCasFilter
{
public static final String CONST_CAS_GATEWAY = "_const_cas_gateway_";
/**
* 本地登陆页面URL.
*/
private String localLoginUrl;
/**
* The URL to the CAS Server login.
*/
private String casServerLoginUrl;
/**
* Whether to send the renew request or not.
*/
private boolean renew = false;
/**
* Whether to send the gateway request or not.
*/
private boolean gateway = false;
protected void initInternal(final FilterConfig filterConfig)
throws ServletException
{
super.initInternal(filterConfig);
setCasServerLoginUrl(getPropertyFromInitParams(filterConfig,
"casServerLoginUrl", null));
log.trace("Loaded CasServerLoginUrl parameter: "
+ this.casServerLoginUrl);
setLocalLoginUrl(getPropertyFromInitParams(filterConfig,
"localLoginUrl", null));
log.trace("Loaded LocalLoginUrl parameter: " + this.localLoginUrl);
setRenew(Boolean.parseBoolean(getPropertyFromInitParams(filterConfig,
"renew", "false")));
log.trace("Loaded renew parameter: " + this.renew);
setGateway(Boolean.parseBoolean(getPropertyFromInitParams(filterConfig,
"gateway", "false")));
log.trace("Loaded gateway parameter: " + this.gateway);
}
public void init()
{
super.init();
CommonUtils.assertNotNull(this.localLoginUrl,
"localLoginUrl cannot be null.");
CommonUtils.assertNotNull(this.casServerLoginUrl,
"casServerLoginUrl cannot be null.");
}
public final void doFilter(final ServletRequest servletRequest,
final ServletResponse servletResponse, final FilterChain filterChain)
throws IOException, ServletException
{
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final HttpSession session = request.getSession(false);
final String ticket = request.getParameter(getArtifactParameterName());
final Assertion assertion = session != null ? (Assertion) session
.getAttribute(CONST_CAS_ASSERTION) : null;
final boolean wasGatewayed = session != null
&& session.getAttribute(CONST_CAS_GATEWAY) != null;
// 如果访问路径为localLoginUrl且带有validated参数则跳过
URL url = new URL(localLoginUrl);
final boolean isValidatedLocalLoginUrl = request.getRequestURI()
.endsWith(url.getPath())
&& CommonUtils.isNotBlank(request.getParameter("validated"));
if (!isValidatedLocalLoginUrl && CommonUtils.isBlank(ticket)
&& assertion == null && !wasGatewayed)
{
log.debug("no ticket and no assertion found");
if (this.gateway)
{
log.debug("setting gateway attribute in session");
request.getSession(true).setAttribute(CONST_CAS_GATEWAY, "yes");
}
final String serviceUrl = constructServiceUrl(request, response);
if (log.isDebugEnabled())
{
log.debug("Constructed service url: " + serviceUrl);
}
String urlToRedirectTo = CommonUtils.constructRedirectUrl(
this.casServerLoginUrl, getServiceParameterName(),
serviceUrl, this.renew, this.gateway);
// 加入localLoginUrl
urlToRedirectTo += (urlToRedirectTo.contains("?") ? "&" : "?")
+ "loginUrl=" + URLEncoder.encode(localLoginUrl, "utf-8");
if (log.isDebugEnabled())
{
log.debug("redirecting to \"" + urlToRedirectTo + "\"");
}
response.sendRedirect(urlToRedirectTo);
return;
}
if (session != null)
{
log.debug("removing gateway attribute from session");
session.setAttribute(CONST_CAS_GATEWAY, null);
}
filterChain.doFilter(request, response);
}
public final void setRenew(final boolean renew)
{
this.renew = renew;
}
public final void setGateway(final boolean gateway)
{
this.gateway = gateway;
}
public final void setCasServerLoginUrl(final String casServerLoginUrl)
{
this.casServerLoginUrl = casServerLoginUrl;
}
public final void setLocalLoginUrl(String localLoginUrl)
{
this.localLoginUrl = localLoginUrl;
}
}
2.web.xml中配置:
旧配置
- <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://localhost:8443/cas/login</param-value>
- </init-param>
- <init-param>
- <param-name>serverName</param-name>
- <param-value>http://localhost:8080</param-value>
- </init-param>
- <init-param>
- <param-name>renew</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>gateway</param-name>
- <param-value>false</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://localhost:8443/cas/login</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://localhost:8080</param-value> </init-param> <init-param> <param-name>renew</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>gateway</param-name> <param-value>false</param-value> </init-param> </filter>
修改成这样,注:其它路径mapping不用改。
- <filter>
- <filter-name>CAS Authentication Filter</filter-name>
- <filter-class>org.demo.user.common.RemoteAuthenticationFilter</filter-class>
- <init-param>
- <param-name>localLoginUrl</param-name>
- <param-value>http://localhost:8080/app/mylogin.jsp</param-value>
- </init-param>
- <init-param>
- <param-name>casServerLoginUrl</param-name>
- <param-value>https://localhost:8443/cas/remoteLogin</param-value>
- </init-param>
- <init-param>
- <param-name>serverName</param-name>
- <param-value>http://localhost:8080</param-value>
- </init-param>
- </filter>
<filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class>org.demo.user.common.RemoteAuthenticationFilter</filter-class> <init-param> <param-name>localLoginUrl</param-name> <param-value>http://localhost:8080/app/mylogin.jsp</param-value> </init-param> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>https://localhost:8443/cas/remoteLogin</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://localhost:8080</param-value> </init-param> </filter>
3.加上你自己定义的登录界面,注:我修改了一些网上介绍的代码:
- <%@ page language="java" contentType="text/html; charset=utf-8"
- pageEncoding="utf-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>APP1客户端登录</title>
- <link rel="stylesheet" type="text/css"
- href="<%=request.getContextPath()%>/styles/main.css" />
- <script type="text/javascript">
- function getParam(name)
- {
- var queryString = window.location.search;
- var param = queryString.substr(1, queryString.length - 1).split("&");
- for (var i = 0; i < param.length; i++)
- {
- var keyValue = param[i].split("=");
- if (keyValue[0] == name)
- return keyValue[1];
- }
- return null;
- }
- function init()
- {
- // 显示异常信息
- var error = getParam("errorMessage");
- if (error)
- {
- document.getElementById("errorMessage").innerHTML = decodeURIComponent(error);
- }
- // 注入service
- var service = getParam("service");
- if (service)
- document.getElementById("service").value = decodeURIComponent(service);
- else
- document.getElementById("service").value = location.href;
- }
- </script>
- </head>
- <body>
- <h1>APP1客户端登录</h1>
- <div id="errorMessage" style="color: red;"></div>
- <form id="myLoginForm" action="https://localhost:8443/cas/remoteLogin?service=http://localhost:8080/app/pages/home.jsp"
- method="post">
- <input type="hidden" name="loginUrl" value="http://localhost:8080/app/mylogin.jsp">
- <input type="hidden" name="submit" value="true" />
- <input type="hidden" name="lt" id="loginTicket" value="" />
- <table>
- <tr>
- <td>用户名:</td>
- <td><input type="text" name="username"></td>
- </tr>
- <tr>
- <td>密 码:</td>
- <td><input type="password" name="password"></td>
- </tr>
- <tr>
- <td colspan="2"><input type="submit" value="登陆" /></td>
- </tr>
- </table>
- </form>
- <script type="text/javascript">
- init()
- </script>
- </body>
- </html>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>APP1客户端登录</title> <link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/styles/main.css" /> <script type="text/javascript"> function getParam(name) { var queryString = window.location.search; var param = queryString.substr(1, queryString.length - 1).split("&"); for (var i = 0; i < param.length; i++) { var keyValue = param[i].split("="); if (keyValue[0] == name) return keyValue[1]; } return null; } function init() { // 显示异常信息 var error = getParam("errorMessage"); if (error) { document.getElementById("errorMessage").innerHTML = decodeURIComponent(error); } // 注入service var service = getParam("service"); if (service) document.getElementById("service").value = decodeURIComponent(service); else document.getElementById("service").value = location.href; } </script> </head> <body> <h1>APP1客户端登录</h1> <div id="errorMessage" style="color: red;"></div> <form id="myLoginForm" action="https://localhost:8443/cas/remoteLogin?service=http://localhost:8080/app/pages/home.jsp" method="post"> <input type="hidden" name="loginUrl" value="http://localhost:8080/app/mylogin.jsp"> <input type="hidden" name="submit" value="true" /> <input type="hidden" name="lt" id="loginTicket" value="" /> <table> <tr> <td>用户名:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>密 码:</td> <td><input type="password" name="password"></td> </tr> <tr> <td colspan="2"><input type="submit" value="登陆" /></td> </tr> </table> </form> <script type="text/javascript"> init() </script> </body> </html>
至此客户端完结!
服务端篇:注我没有加上登出代码,因为登出代码可以使用原有的
1.添加客户端登录Action,org.jasig.cas.web.flow.RemoteLoginAction:
- /**
- * 远程登陆票据提供Action. 根据InitialFlowSetupAction修改.
- * 由于InitialFlowSetupAction为final类,因此只能将代码复制过来再进行修改.
- */
- public class RemoteLoginAction extends AbstractAction
- {
- /** CookieGenerator for the Warnings. */
- @NotNull
- private CookieRetrievingCookieGenerator warnCookieGenerator;
- /** CookieGenerator for the TicketGrantingTickets. */
- @NotNull
- private CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator;
- /** Extractors for finding the service. */
- @NotNull
- @Size(min = 1)
- private List<ArgumentExtractor> argumentExtractors;
- /** Boolean to note whether we've set the values on the generators or not. */
- private boolean pathPopulated = false;
- protected Event doExecute(final RequestContext context) throws Exception
- {
- final HttpServletRequest request = WebUtils
- .getHttpServletRequest(context);
- if (!this.pathPopulated)
- {
- final String contextPath = context.getExternalContext()
- .getContextPath();
- final String cookiePath = StringUtils.hasText(contextPath) ? contextPath
- : "/";
- logger.info("Setting path for cookies to: " + cookiePath);
- this.warnCookieGenerator.setCookiePath(cookiePath);
- this.ticketGrantingTicketCookieGenerator.setCookiePath(cookiePath);
- this.pathPopulated = true;
- }
- context.getFlowScope().put(
- "ticketGrantingTicketId",
- this.ticketGrantingTicketCookieGenerator
- .retrieveCookieValue(request));
- context.getFlowScope().put(
- "warnCookieValue",
- Boolean.valueOf(this.warnCookieGenerator
- .retrieveCookieValue(request)));
- // 存放service url
- // context.getFlowScope().put("serviceUrl", request.getParameter("service"));
- final Service service = WebUtils.getService(this.argumentExtractors,
- context);
- if (service != null && logger.isDebugEnabled())
- {
- logger.debug("Placing service in FlowScope: " + service.getId());
- }
- context.getFlowScope().put("service", service);
- // 客户端必须传递loginUrl参数过来,否则无法确定登陆目标页面
- if (StringUtils.hasText(request.getParameter("loginUrl")))
- {
- context.getFlowScope().put("remoteLoginUrl",
- request.getParameter("loginUrl"));
- } else
- {
- request.setAttribute("remoteLoginMessage",
- "loginUrl parameter must be supported.");
- return error();
- }
- // 若参数包含submit则进行提交,否则进行验证
- if (StringUtils.hasText(request.getParameter("submit")))
- {
- return result("submit");
- } else
- {
- return result("checkTicketGrantingTicket");
- }
- }
- public void setTicketGrantingTicketCookieGenerator(
- final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator)
- {
- this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator;
- }
- public void setWarnCookieGenerator(
- final CookieRetrievingCookieGenerator warnCookieGenerator)
- {
- this.warnCookieGenerator = warnCookieGenerator;
- }
- public void setArgumentExtractors(
- final List<ArgumentExtractor> argumentExtractors)
- {
- this.argumentExtractors = argumentExtractors;
- }
- }
/**
* 远程登陆票据提供Action. 根据InitialFlowSetupAction修改.
* 由于InitialFlowSetupAction为final类,因此只能将代码复制过来再进行修改.
*/
public class RemoteLoginAction extends AbstractAction
{
/** CookieGenerator for the Warnings. */
@NotNull
private CookieRetrievingCookieGenerator warnCookieGenerator;
/** CookieGenerator for the TicketGrantingTickets. */
@NotNull
private CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator;
/** Extractors for finding the service. */
@NotNull
@Size(min = 1)
private List<ArgumentExtractor> argumentExtractors;
/** Boolean to note whether we've set the values on the generators or not. */
private boolean pathPopulated = false;
protected Event doExecute(final RequestContext context) throws Exception
{
final HttpServletRequest request = WebUtils
.getHttpServletRequest(context);
if (!this.pathPopulated)
{
final String contextPath = context.getExternalContext()
.getContextPath();
final String cookiePath = StringUtils.hasText(contextPath) ? contextPath
: "/";
logger.info("Setting path for cookies to: " + cookiePath);
this.warnCookieGenerator.setCookiePath(cookiePath);
this.ticketGrantingTicketCookieGenerator.setCookiePath(cookiePath);
this.pathPopulated = true;
}
context.getFlowScope().put(
"ticketGrantingTicketId",
this.ticketGrantingTicketCookieGenerator
.retrieveCookieValue(request));
context.getFlowScope().put(
"warnCookieValue",
Boolean.valueOf(this.warnCookieGenerator
.retrieveCookieValue(request)));
// 存放service url
// context.getFlowScope().put("serviceUrl", request.getParameter("service"));
final Service service = WebUtils.getService(this.argumentExtractors,
context);
if (service != null && logger.isDebugEnabled())
{
logger.debug("Placing service in FlowScope: " + service.getId());
}
context.getFlowScope().put("service", service);
// 客户端必须传递loginUrl参数过来,否则无法确定登陆目标页面
if (StringUtils.hasText(request.getParameter("loginUrl")))
{
context.getFlowScope().put("remoteLoginUrl",
request.getParameter("loginUrl"));
} else
{
request.setAttribute("remoteLoginMessage",
"loginUrl parameter must be supported.");
return error();
}
// 若参数包含submit则进行提交,否则进行验证
if (StringUtils.hasText(request.getParameter("submit")))
{
return result("submit");
} else
{
return result("checkTicketGrantingTicket");
}
}
public void setTicketGrantingTicketCookieGenerator(
final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator)
{
this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator;
}
public void setWarnCookieGenerator(
final CookieRetrievingCookieGenerator warnCookieGenerator)
{
this.warnCookieGenerator = warnCookieGenerator;
}
public void setArgumentExtractors(
final List<ArgumentExtractor> argumentExtractors)
{
this.argumentExtractors = argumentExtractors;
}
}
2.重写LoginForm代码,org.jasig.cas.web.flow.AuthenticationViaFormAction重写,此类基本上采用原有代码,只是添加了获取用户名与密码的代码:
- public class AuthenticationViaFormAction
- {
- /**
- * Binder that allows additional binding of form object beyond Spring
- * defaults.
- */
- private CredentialsBinder credentialsBinder;
- /** Core we delegate to for handling all ticket related tasks. */
- @NotNull
- private CentralAuthenticationService centralAuthenticationService;
- @NotNull
- private CookieGenerator warnCookieGenerator;
- protected Logger logger = LoggerFactory.getLogger(getClass());
- public final void doBind(final RequestContext context,
- final Credentials credentials) throws Exception
- {
- final HttpServletRequest request = WebUtils
- .getHttpServletRequest(context);
- if (this.credentialsBinder != null
- && this.credentialsBinder.supports(credentials.getClass()))
- {
- this.credentialsBinder.bind(request, credentials);
- }
- }
- public final String submit(final RequestContext context,
- final MessageContext messageContext) throws Exception
- {
- // Validate login ticket
- final String authoritativeLoginTicket = WebUtils
- .getLoginTicketFromFlowScope(context);
- final String providedLoginTicket = WebUtils
- .getLoginTicketFromRequest(context);
- if (!authoritativeLoginTicket.equals(providedLoginTicket))
- {
- this.logger.warn("Invalid login ticket " + providedLoginTicket);
- final String code = "INVALID_TICKET";
- messageContext.addMessage(new MessageBuilder().error().code(code)
- .arg(providedLoginTicket).defaultText(code).build());
- return "error";
- }
- final String ticketGrantingTicketId = WebUtils
- .getTicketGrantingTicketId(context);
- final Service service = WebUtils.getService(context);
- final HttpServletRequest request = WebUtils
- .getHttpServletRequest(context);
- org.jasig.cas.authentication.principal.UsernamePasswordCredentials credentials = new org.jasig.cas.authentication.principal.UsernamePasswordCredentials();
- credentials.setPassword(request.getParameter("password"));
- credentials.setUsername(request.getParameter("username"));
- if (StringUtils.hasText(context.getRequestParameters().get("renew"))
- && ticketGrantingTicketId != null && service != null)
- {
- try
- {
- final String serviceTicketId = this.centralAuthenticationService
- .grantServiceTicket(ticketGrantingTicketId, service,
- credentials);
- WebUtils.putServiceTicketInRequestScope(context,
- serviceTicketId);
- putWarnCookieIfRequestParameterPresent(context);
- return "warn";
- } catch (final TicketException e)
- {
- if (e.getCause() != null
- && AuthenticationException.class.isAssignableFrom(e
- .getCause().getClass()))
- {
- populateErrorsInstance(context, e, messageContext);
- return "error";
- }
- this.centralAuthenticationService
- .destroyTicketGrantingTicket(ticketGrantingTicketId);
- if (logger.isDebugEnabled())
- {
- logger.debug(
- "Attempted to generate a ServiceTicket using renew=true with different credentials",
- e);
- }
- }
- }
- try
- {
- WebUtils.putTicketGrantingTicketInRequestScope(context,
- this.centralAuthenticationService
- .createTicketGrantingTicket(credentials));
- putWarnCookieIfRequestParameterPresent(context);
- return "success";
- } catch (final TicketException e)
- {
- populateErrorsInstance(context, e, messageContext);
- return "error";
- }
- }
- public final String submit(final RequestContext context,
- final Credentials credentials, final MessageContext messageContext)
- throws Exception
- {
- // Validate login ticket
- final String authoritativeLoginTicket = WebUtils
- .getLoginTicketFromFlowScope(context);
- final String providedLoginTicket = WebUtils
- .getLoginTicketFromRequest(context);
- if (!authoritativeLoginTicket.equals(providedLoginTicket))
- {
- this.logger.warn("Invalid login ticket " + providedLoginTicket);
- final String code = "INVALID_TICKET";
- messageContext.addMessage(new MessageBuilder().error().code(code)
- .arg(providedLoginTicket).defaultText(code).build());
- return "error";
- }
- final String ticketGrantingTicketId = WebUtils
- .getTicketGrantingTicketId(context);
- final Service service = WebUtils.getService(context);
- if (StringUtils.hasText(context.getRequestParameters().get("renew"))
- && ticketGrantingTicketId != null && service != null)
- {
- try
- {
- final String serviceTicketId = this.centralAuthenticationService
- .grantServiceTicket(ticketGrantingTicketId, service,
- credentials);
- WebUtils.putServiceTicketInRequestScope(context,
- serviceTicketId);
- putWarnCookieIfRequestParameterPresent(context);
- return "warn";
- } catch (final TicketException e)
- {
- if (isCauseAuthenticationException(e))
- {
- populateErrorsInstance(e, messageContext);
- return getAuthenticationExceptionEventId(e);
- }
- this.centralAuthenticationService
- .destroyTicketGrantingTicket(ticketGrantingTicketId);
- if (logger.isDebugEnabled())
- {
- logger.debug(
- "Attempted to generate a ServiceTicket using renew=true with different credentials",
- e);
- }
- }
- }
- try
- {
- WebUtils.putTicketGrantingTicketInRequestScope(context,
- this.centralAuthenticationService
- .createTicketGrantingTicket(credentials));
- putWarnCookieIfRequestParameterPresent(context);
- return "success";
- } catch (final TicketException e)
- {
- populateErrorsInstance(e, messageContext);
- if (isCauseAuthenticationException(e))
- return getAuthenticationExceptionEventId(e);
- return "error";
- }
- }
- private void populateErrorsInstance(final TicketException e,
- final MessageContext messageContext)
- {
- try
- {
- messageContext.addMessage(new MessageBuilder().error()
- .code(e.getCode()).defaultText(e.getCode()).build());
- } catch (final Exception fe)
- {
- logger.error(fe.getMessage(), fe);
- }
- }
- private void populateErrorsInstance(final RequestContext context,
- final TicketException e, final MessageContext messageContext)
- {
- try
- {
- messageContext.addMessage(new MessageBuilder().error()
- .code(e.getCode()).defaultText(e.getCode()).build());
- Message[] messages = messageContext.getAllMessages();
- context.getFlowScope().put("remoteLoginMessage",
- messages[messages.length - 1].getText());
- } catch (final Exception fe)
- {
- logger.error(fe.getMessage(), fe);
- }
- }
- private void putWarnCookieIfRequestParameterPresent(
- final RequestContext context)
- {
- final HttpServletResponse response = WebUtils
- .getHttpServletResponse(context);
- if (StringUtils.hasText(context.getExternalContext()
- .getRequestParameterMap().get("warn")))
- {
- this.warnCookieGenerator.addCookie(response, "true");
- } else
- {
- this.warnCookieGenerator.removeCookie(response);
- }
- }
- private AuthenticationException getAuthenticationExceptionAsCause(
- final TicketException e)
- {
- return (AuthenticationException) e.getCause();
- }
- private String getAuthenticationExceptionEventId(final TicketException e)
- {
- final AuthenticationException authEx = getAuthenticationExceptionAsCause(e);
- if (this.logger.isDebugEnabled())
- this.logger
- .debug("An authentication error has occurred. Returning the event id "
- + authEx.getType());
- return authEx.getType();
- }
- private boolean isCauseAuthenticationException(final TicketException e)
- {
- return e.getCause() != null
- && AuthenticationException.class.isAssignableFrom(e.getCause()
- .getClass());
- }
- public final void setCentralAuthenticationService(
- final CentralAuthenticationService centralAuthenticationService)
- {
- this.centralAuthenticationService = centralAuthenticationService;
- }
- /**
- * Set a CredentialsBinder for additional binding of the HttpServletRequest
- * to the Credentials instance, beyond our default binding of the
- * Credentials as a Form Object in Spring WebMVC parlance. By the time we
- * invoke this CredentialsBinder, we have already engaged in default binding
- * such that for each HttpServletRequest parameter, if there was a JavaBean
- * property of the Credentials implementation of the same name, we have set
- * that property to be the value of the corresponding request parameter.
- * This CredentialsBinder plugin point exists to allow consideration of
- * things other than HttpServletRequest parameters in populating the
- * Credentials (or more sophisticated consideration of the
- * HttpServletRequest parameters).
- *
- * @param credentialsBinder
- * the credentials binder to set.
- */
- public final void setCredentialsBinder(
- final CredentialsBinder credentialsBinder)
- {
- this.credentialsBinder = credentialsBinder;
- }
- public final void setWarnCookieGenerator(
- final CookieGenerator warnCookieGenerator)
- {
- this.warnCookieGenerator = warnCookieGenerator;
- }
- }
public class AuthenticationViaFormAction
{
/**
* Binder that allows additional binding of form object beyond Spring
* defaults.
*/
private CredentialsBinder credentialsBinder;
/** Core we delegate to for handling all ticket related tasks. */
@NotNull
private CentralAuthenticationService centralAuthenticationService;
@NotNull
private CookieGenerator warnCookieGenerator;
protected Logger logger = LoggerFactory.getLogger(getClass());
public final void doBind(final RequestContext context,
final Credentials credentials) throws Exception
{
final HttpServletRequest request = WebUtils
.getHttpServletRequest(context);
if (this.credentialsBinder != null
&& this.credentialsBinder.supports(credentials.getClass()))
{
this.credentialsBinder.bind(request, credentials);
}
}
public final String submit(final RequestContext context,
final MessageContext messageContext) throws Exception
{
// Validate login ticket
final String authoritativeLoginTicket = WebUtils
.getLoginTicketFromFlowScope(context);
final String providedLoginTicket = WebUtils
.getLoginTicketFromRequest(context);
if (!authoritativeLoginTicket.equals(providedLoginTicket))
{
this.logger.warn("Invalid login ticket " + providedLoginTicket);
final String code = "INVALID_TICKET";
messageContext.addMessage(new MessageBuilder().error().code(code)
.arg(providedLoginTicket).defaultText(code).build());
return "error";
}
final String ticketGrantingTicketId = WebUtils
.getTicketGrantingTicketId(context);
final Service service = WebUtils.getService(context);
final HttpServletRequest request = WebUtils
.getHttpServletRequest(context);
org.jasig.cas.authentication.principal.UsernamePasswordCredentials credentials = new org.jasig.cas.authentication.principal.UsernamePasswordCredentials();
credentials.setPassword(request.getParameter("password"));
credentials.setUsername(request.getParameter("username"));
if (StringUtils.hasText(context.getRequestParameters().get("renew"))
&& ticketGrantingTicketId != null && service != null)
{
try
{
final String serviceTicketId = this.centralAuthenticationService
.grantServiceTicket(ticketGrantingTicketId, service,
credentials);
WebUtils.putServiceTicketInRequestScope(context,
serviceTicketId);
putWarnCookieIfRequestParameterPresent(context);
return "warn";
} catch (final TicketException e)
{
if (e.getCause() != null
&& AuthenticationException.class.isAssignableFrom(e
.getCause().getClass()))
{
populateErrorsInstance(context, e, messageContext);
return "error";
}
this.centralAuthenticationService
.destroyTicketGrantingTicket(ticketGrantingTicketId);
if (logger.isDebugEnabled())
{
logger.debug(
"Attempted to generate a ServiceTicket using renew=true with different credentials",
e);
}
}
}
try
{
WebUtils.putTicketGrantingTicketInRequestScope(context,
this.centralAuthenticationService
.createTicketGrantingTicket(credentials));
putWarnCookieIfRequestParameterPresent(context);
return "success";
} catch (final TicketException e)
{
populateErrorsInstance(context, e, messageContext);
return "error";
}
}
public final String submit(final RequestContext context,
final Credentials credentials, final MessageContext messageContext)
throws Exception
{
// Validate login ticket
final String authoritativeLoginTicket = WebUtils
.getLoginTicketFromFlowScope(context);
final String providedLoginTicket = WebUtils
.getLoginTicketFromRequest(context);
if (!authoritativeLoginTicket.equals(providedLoginTicket))
{
this.logger.warn("Invalid login ticket " + providedLoginTicket);
final String code = "INVALID_TICKET";
messageContext.addMessage(new MessageBuilder().error().code(code)
.arg(providedLoginTicket).defaultText(code).build());
return "error";
}
final String ticketGrantingTicketId = WebUtils
.getTicketGrantingTicketId(context);
final Service service = WebUtils.getService(context);
if (StringUtils.hasText(context.getRequestParameters().get("renew"))
&& ticketGrantingTicketId != null && service != null)
{
try
{
final String serviceTicketId = this.centralAuthenticationService
.grantServiceTicket(ticketGrantingTicketId, service,
credentials);
WebUtils.putServiceTicketInRequestScope(context,
serviceTicketId);
putWarnCookieIfRequestParameterPresent(context);
return "warn";
} catch (final TicketException e)
{
if (isCauseAuthenticationException(e))
{
populateErrorsInstance(e, messageContext);
return getAuthenticationExceptionEventId(e);
}
this.centralAuthenticationService
.destroyTicketGrantingTicket(ticketGrantingTicketId);
if (logger.isDebugEnabled())
{
logger.debug(
"Attempted to generate a ServiceTicket using renew=true with different credentials",
e);
}
}
}
try
{
WebUtils.putTicketGrantingTicketInRequestScope(context,
this.centralAuthenticationService
.createTicketGrantingTicket(credentials));
putWarnCookieIfRequestParameterPresent(context);
return "success";
} catch (final TicketException e)
{
populateErrorsInstance(e, messageContext);
if (isCauseAuthenticationException(e))
return getAuthenticationExceptionEventId(e);
return "error";
}
}
private void populateErrorsInstance(final TicketException e,
final MessageContext messageContext)
{
try
{
messageContext.addMessage(new MessageBuilder().error()
.code(e.getCode()).defaultText(e.getCode()).build());
} catch (final Exception fe)
{
logger.error(fe.getMessage(), fe);
}
}
private void populateErrorsInstance(final RequestContext context,
final TicketException e, final MessageContext messageContext)
{
try
{
messageContext.addMessage(new MessageBuilder().error()
.code(e.getCode()).defaultText(e.getCode()).build());
Message[] messages = messageContext.getAllMessages();
context.getFlowScope().put("remoteLoginMessage",
messages[messages.length - 1].getText());
} catch (final Exception fe)
{
logger.error(fe.getMessage(), fe);
}
}
private void putWarnCookieIfRequestParameterPresent(
final RequestContext context)
{
final HttpServletResponse response = WebUtils
.getHttpServletResponse(context);
if (StringUtils.hasText(context.getExternalContext()
.getRequestParameterMap().get("warn")))
{
this.warnCookieGenerator.addCookie(response, "true");
} else
{
this.warnCookieGenerator.removeCookie(response);
}
}
private AuthenticationException getAuthenticationExceptionAsCause(
final TicketException e)
{
return (AuthenticationException) e.getCause();
}
private String getAuthenticationExceptionEventId(final TicketException e)
{
final AuthenticationException authEx = getAuthenticationExceptionAsCause(e);
if (this.logger.isDebugEnabled())
this.logger
.debug("An authentication error has occurred. Returning the event id "
+ authEx.getType());
return authEx.getType();
}
private boolean isCauseAuthenticationException(final TicketException e)
{
return e.getCause() != null
&& AuthenticationException.class.isAssignableFrom(e.getCause()
.getClass());
}
public final void setCentralAuthenticationService(
final CentralAuthenticationService centralAuthenticationService)
{
this.centralAuthenticationService = centralAuthenticationService;
}
/**
* Set a CredentialsBinder for additional binding of the HttpServletRequest
* to the Credentials instance, beyond our default binding of the
* Credentials as a Form Object in Spring WebMVC parlance. By the time we
* invoke this CredentialsBinder, we have already engaged in default binding
* such that for each HttpServletRequest parameter, if there was a JavaBean
* property of the Credentials implementation of the same name, we have set
* that property to be the value of the corresponding request parameter.
* This CredentialsBinder plugin point exists to allow consideration of
* things other than HttpServletRequest parameters in populating the
* Credentials (or more sophisticated consideration of the
* HttpServletRequest parameters).
*
* @param credentialsBinder
* the credentials binder to set.
*/
public final void setCredentialsBinder(
final CredentialsBinder credentialsBinder)
{
this.credentialsBinder = credentialsBinder;
}
public final void setWarnCookieGenerator(
final CookieGenerator warnCookieGenerator)
{
this.warnCookieGenerator = warnCookieGenerator;
}
}
3.web.xml配置,原有基础上新增这两句:
- <servlet-mapping>
- <servlet-name>cas</servlet-name>
- <url-pattern>/remoteLogin</url-pattern>
- </servlet-mapping>
<servlet-mapping> <servlet-name>cas</servlet-name> <url-pattern>/remoteLogin</url-pattern> </servlet-mapping>
4.在cas-servlet.xml中最后面增加以下信息:
- <bean id="handlerMappingB"
- class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="mappings">
- <props>
- <prop key="/remoteLogin">remoteLoginController</prop>
- </props>
- </property>
- <property name="interceptors">
- <list>
- <ref bean="localeChangeInterceptor" />
- </list>
- </property>
- </bean>
- <bean id="remoteLoginController" class="org.springframework.webflow.mvc.servlet.FlowController">
- <property name="flowExecutor" ref="remoteLoginFlowExecutor" />
- <property name="flowUrlHandler" ref="flowUrlHandler" />
- </bean>
- <webflow:flow-executor id="remoteLoginFlowExecutor"
- flow-registry="remoteLoginFlowRegistry">
- <webflow:flow-execution-attributes>
- <webflow:always-redirect-on-pause
- value="false" />
- </webflow:flow-execution-attributes>
- </webflow:flow-executor>
- <webflow:flow-registry id="remoteLoginFlowRegistry"
- flow-builder-services="builder">
- <webflow:flow-location path="/WEB-INF/remoteLogin-webflow.xml"
- id="remoteLogin" />
- </webflow:flow-registry>
- <webflow:flow-builder-services id="flowBuilderServices"
- view-factory-creator="viewFactoryCreator" />
- <bean id="remoteLoginAction" class="org.jasig.cas.web.flow.RemoteLoginAction"
- p:argumentExtractors-ref="argumentExtractors"
- p:warnCookieGenerator-ref="warnCookieGenerator"
- p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator" />
- <bean id="remoteLogoutController" class="org.springframework.webflow.mvc.servlet.FlowController">
- <property name="flowExecutor" ref="remoteLogoutFlowExecutor" />
- <property name="flowUrlHandler" ref="flowUrlHandler" />
- </bean>
<bean id="handlerMappingB" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/remoteLogin">remoteLoginController</prop> </props> </property> <property name="interceptors"> <list> <ref bean="localeChangeInterceptor" /> </list> </property> </bean> <bean id="remoteLoginController" class="org.springframework.webflow.mvc.servlet.FlowController"> <property name="flowExecutor" ref="remoteLoginFlowExecutor" /> <property name="flowUrlHandler" ref="flowUrlHandler" /> </bean> <webflow:flow-executor id="remoteLoginFlowExecutor" flow-registry="remoteLoginFlowRegistry"> <webflow:flow-execution-attributes> <webflow:always-redirect-on-pause value="false" /> </webflow:flow-execution-attributes> </webflow:flow-executor> <webflow:flow-registry id="remoteLoginFlowRegistry" flow-builder-services="builder"> <webflow:flow-location path="/WEB-INF/remoteLogin-webflow.xml" id="remoteLogin" /> </webflow:flow-registry> <webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="viewFactoryCreator" /> <bean id="remoteLoginAction" class="org.jasig.cas.web.flow.RemoteLoginAction" p:argumentExtractors-ref="argumentExtractors" p:warnCookieGenerator-ref="warnCookieGenerator" p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator" /> <bean id="remoteLogoutController" class="org.springframework.webflow.mvc.servlet.FlowController"> <property name="flowExecutor" ref="remoteLogoutFlowExecutor" /> <property name="flowUrlHandler" ref="flowUrlHandler" /> </bean>
5.新建一个文件与login-webflow.xml同级,remoteLogin-webflow.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <flow xmlns="http://www.springframework.org/schema/webflow"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/webflow
- http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
- start-state="remoteLogin">
- <!-- <on-start> <evaluate expression="remoteLoginAction.doBind(flowRequestContext,
- flowScope.credentials)" /> </on-start> -->
- <var name="credentials"
- class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" />
- <!-- 远程登陆主要Action -->
- <action-state id="remoteLogin">
- <evaluate expression="remoteLoginAction" />
- <transition on="error" to="remoteCallbackView" />
- <transition on="submit" to="bindAndValidate" />
- <transition on="checkTicketGrantingTicket" to="ticketGrantingTicketExistsCheck" />
- </action-state>
- <!-- 远程回调页面,主要以JavaScript的方式回传一些参数用 -->
- <end-state id="remoteCallbackView" view="remoteCallbackView" />
- <action-state id="bindAndValidate">
- <evaluate
- expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />
- <transition on="success" to="submit" />
- <transition on="error" to="remoteCallbackView" />
- </action-state>
- <decision-state id="ticketGrantingTicketExistsCheck">
- <if test="flowScope.ticketGrantingTicketId != null" then="hasServiceCheck"
- else="gatewayRequestCheck" />
- </decision-state>
- <decision-state id="hasServiceCheck">
- <if test="flowScope.service != null" then="generateServiceTicket"
- else="remoteCallbackView" />
- </decision-state>
- <decision-state id="gatewayRequestCheck">
- <if
- test="externalContext.requestParameterMap['gateway'] neq '' && externalContext.requestParameterMap['gateway'] neq null && flowScope.service neq null"
- then="redirect" else="remoteCallbackView" />
- </decision-state>
- <action-state id="generateServiceTicket">
- <evaluate expression="generateServiceTicketAction" />
- <transition on="success" to="warn" />
- <transition on="error" to="remoteCallbackView" />
- <transition on="gateway" to="redirect" />
- </action-state>
- <decision-state id="warn">
- <if test="flowScope.warnCookieValue" then="showWarningView" else="redirect" />
- </decision-state>
- <action-state id="submit">
- <evaluate
- expression="authenticationViaFormAction.submit(flowRequestContext, messageContext)" />
- <transition on="warn" to="warn" />
- <transition on="success" to="sendTicketGrantingTicket" />
- <transition on="error" to="remoteCallbackView" />
- </action-state>
- <action-state id="sendTicketGrantingTicket">
- <evaluate expression="sendTicketGrantingTicketAction" />
- <transition to="serviceCheck" />
- </action-state>
- <decision-state id="serviceCheck">
- <if test="flowScope.service neq null" then="generateServiceTicket"
- else="remoteCallbackView" />
- </decision-state>
- <end-state id="showWarningView" view="casLoginConfirmView" />
- <!-- <end-state id="redirect" view="bean:dynamicRedirectViewSelector" /> -->
- <action-state id="redirect">
- <evaluate
- expression="flowScope.service.getResponse(requestScope.serviceTicketId)"
- result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response" />
- <transition to="postRedirectDecision" />
- </action-state>
- <decision-state id="postRedirectDecision">
- <if test="requestScope.response.responseType.name() eq 'POST'"
- then="postView" else="redirectView" />
- </decision-state>
- <!-- <decision-state id="hashServiceUrl">
- <if test="flowScope.serviceUrl neq null" then="redirectServiceView" else="redirectView"/>
- </decision-state>
- <end-state id="redirectServiceView" view="externalRedirect:${flowScope.serviceUrl}" /> -->
- <end-state id="postView" view="postResponseView">
- <on-entry>
- <set name="requestScope.parameters" value="requestScope.response.attributes" />
- <set name="requestScope.originalUrl" value="flowScope.service.id" />
- </on-entry>
- </end-state>
- <end-state id="redirectView" view="externalRedirect:${requestScope.response.url}" />
- <end-state id="viewServiceErrorView" view="viewServiceErrorView" />
- <end-state id="viewServiceSsoErrorView" view="viewServiceSsoErrorView" />
- <global-transitions>
- <transition to="viewServiceErrorView"
- on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException" />
- <transition to="viewServiceSsoErrorView"
- on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException" />
- <transition to="viewServiceErrorView"
- on-exception="org.jasig.cas.services.UnauthorizedServiceException" />
- </global-transitions>
- </flow>
<?xml version="1.0" encoding="UTF-8"?> <flow xmlns="http://www.springframework.org/schema/webflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd" start-state="remoteLogin"> <!-- <on-start> <evaluate expression="remoteLoginAction.doBind(flowRequestContext, flowScope.credentials)" /> </on-start> --> <var name="credentials" class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" /> <!-- 远程登陆主要Action --> <action-state id="remoteLogin"> <evaluate expression="remoteLoginAction" /> <transition on="error" to="remoteCallbackView" /> <transition on="submit" to="bindAndValidate" /> <transition on="checkTicketGrantingTicket" to="ticketGrantingTicketExistsCheck" /> </action-state> <!-- 远程回调页面,主要以JavaScript的方式回传一些参数用 --> <end-state id="remoteCallbackView" view="remoteCallbackView" /> <action-state id="bindAndValidate"> <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" /> <transition on="success" to="submit" /> <transition on="error" to="remoteCallbackView" /> </action-state> <decision-state id="ticketGrantingTicketExistsCheck"> <if test="flowScope.ticketGrantingTicketId != null" then="hasServiceCheck" else="gatewayRequestCheck" /> </decision-state> <decision-state id="hasServiceCheck"> <if test="flowScope.service != null" then="generateServiceTicket" else="remoteCallbackView" /> </decision-state> <decision-state id="gatewayRequestCheck"> <if test="externalContext.requestParameterMap['gateway'] neq '' && externalContext.requestParameterMap['gateway'] neq null && flowScope.service neq null" then="redirect" else="remoteCallbackView" /> </decision-state> <action-state id="generateServiceTicket"> <evaluate expression="generateServiceTicketAction" /> <transition on="success" to="warn" /> <transition on="error" to="remoteCallbackView" /> <transition on="gateway" to="redirect" /> </action-state> <decision-state id="warn"> <if test="flowScope.warnCookieValue" then="showWarningView" else="redirect" /> </decision-state> <action-state id="submit"> <evaluate expression="authenticationViaFormAction.submit(flowRequestContext, messageContext)" /> <transition on="warn" to="warn" /> <transition on="success" to="sendTicketGrantingTicket" /> <transition on="error" to="remoteCallbackView" /> </action-state> <action-state id="sendTicketGrantingTicket"> <evaluate expression="sendTicketGrantingTicketAction" /> <transition to="serviceCheck" /> </action-state> <decision-state id="serviceCheck"> <if test="flowScope.service neq null" then="generateServiceTicket" else="remoteCallbackView" /> </decision-state> <end-state id="showWarningView" view="casLoginConfirmView" /> <!-- <end-state id="redirect" view="bean:dynamicRedirectViewSelector" /> --> <action-state id="redirect"> <evaluate expression="flowScope.service.getResponse(requestScope.serviceTicketId)" result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response" /> <transition to="postRedirectDecision" /> </action-state> <decision-state id="postRedirectDecision"> <if test="requestScope.response.responseType.name() eq 'POST'" then="postView" else="redirectView" /> </decision-state> <!-- <decision-state id="hashServiceUrl"> <if test="flowScope.serviceUrl neq null" then="redirectServiceView" else="redirectView"/> </decision-state> <end-state id="redirectServiceView" view="externalRedirect:${flowScope.serviceUrl}" /> --> <end-state id="postView" view="postResponseView"> <on-entry> <set name="requestScope.parameters" value="requestScope.response.attributes" /> <set name="requestScope.originalUrl" value="flowScope.service.id" /> </on-entry> </end-state> <end-state id="redirectView" view="externalRedirect:${requestScope.response.url}" /> <end-state id="viewServiceErrorView" view="viewServiceErrorView" /> <end-state id="viewServiceSsoErrorView" view="viewServiceSsoErrorView" /> <global-transitions> <transition to="viewServiceErrorView" on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException" /> <transition to="viewServiceSsoErrorView" on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException" /> <transition to="viewServiceErrorView" on-exception="org.jasig.cas.services.UnauthorizedServiceException" /> </global-transitions> </flow>
6.加上一个回调视图配置,在default_views.properties中新增以下两句:
### 配置远程回调页面
remoteCallbackView.(class)=org.springframework.web.servlet.view.JstlView
remoteCallbackView.url=/WEB-INF/view/jsp/default/ui/remoteCallbackView.jsp
其它不变
7.加上回调页面jsp:
- <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
- <%-- <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
- <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> --%>
- <script type="text/javascript">
- var remoteUrl = "${remoteLoginUrl}?validated=true";
- // 构造错误消息,从webflow scope中取出
- var errorMessage = '${remoteLoginMessage}';
- /* <spring:hasBindErrors name="credentials">
- errorMessage = "&errorMessage=" + encodeURIComponent('<c:forEach var="error" items="${errors.allErrors}"><spring:message code="${error.code}" text="${error.defaultMessage}" /></c:forEach>');
- </spring:hasBindErrors> */
- // 如果存在错误消息则追加到 url中
- if(null != errorMessage && errorMessage.length > 0)
- {
- errorMessage = "&errorMessage=" + encodeURIComponent(errorMessage);
- }
- // 构造service
- var service = "";
- <c:if test="${service != null && service != ''}">
- service = "&service=" + encodeURIComponent("${service}");
- </c:if>
- // 跳转回去(客户端)
- window.location.href = remoteUrl + errorMessage + service;
- </script>