CAS 客户端自定义用户登陆界面

来源:互联网 发布:php 视频防盗链 编辑:程序博客网 时间:2024/06/05 05:31

客户端篇:
1.替换原来过滤器org.jasig.cas.client.authentication.AuthenticationFilter,改成自己的过滤器RemoteAuthenticationFilter.java,这个过滤器可以自己随便放到哪个包中,保证web.xml能够正确引用到就行:

Java代码
  1. public class RemoteAuthenticationFilter extends AbstractCasFilter   
  2. {   
  3.     public static final String CONST_CAS_GATEWAY = "_const_cas_gateway_";   
  4.     /**  
  5.      * 本地登陆页面URL.  
  6.      */  
  7.     private String localLoginUrl;   
  8.        
  9.     /**  
  10.      * The URL to the CAS Server login. 
  11.      */  
  12.     private String casServerLoginUrl;   
  13.     /**  
  14.      * Whether to send the renew request or not. 
  15.      */  
  16.     private boolean renew = false;   
  17.     /**  
  18.      * Whether to send the gateway request or not. 
  19.      */  
  20.     private boolean gateway = false;   
  21.        
  22.     protected void initInternal(final FilterConfig filterConfig)   
  23.             throws ServletException   
  24.     {   
  25.         super.initInternal(filterConfig);   
  26.         setCasServerLoginUrl(getPropertyFromInitParams(filterConfig,   
  27.                 "casServerLoginUrl"null));   
  28.         log.trace("Loaded CasServerLoginUrl parameter: "  
  29.                 + this.casServerLoginUrl);   
  30.         setLocalLoginUrl(getPropertyFromInitParams(filterConfig,   
  31.                 "localLoginUrl"null));   
  32.         log.trace("Loaded LocalLoginUrl parameter: " + this.localLoginUrl);   
  33.         setRenew(Boolean.parseBoolean(getPropertyFromInitParams(filterConfig,   
  34.                 "renew""false")));   
  35.         log.trace("Loaded renew parameter: " + this.renew);   
  36.         setGateway(Boolean.parseBoolean(getPropertyFromInitParams(filterConfig,   
  37.                 "gateway""false")));   
  38.         log.trace("Loaded gateway parameter: " + this.gateway);   
  39.     }   
  40.        
  41.     public void init()   
  42.     {   
  43.         super.init();   
  44.         CommonUtils.assertNotNull(this.localLoginUrl,   
  45.                 "localLoginUrl cannot be null.");   
  46.         CommonUtils.assertNotNull(this.casServerLoginUrl,   
  47.                 "casServerLoginUrl cannot be null.");   
  48.     }   
  49.        
  50.     public final void doFilter(final ServletRequest servletRequest,   
  51.             final ServletResponse servletResponse, final FilterChain filterChain)   
  52.             throws IOException, ServletException   
  53.     {   
  54.         final HttpServletRequest request = (HttpServletRequest) servletRequest;   
  55.         final HttpServletResponse response = (HttpServletResponse) servletResponse;   
  56.         final HttpSession session = request.getSession(false);   
  57.         final String ticket = request.getParameter(getArtifactParameterName());   
  58.         final Assertion assertion = session != null ? (Assertion) session   
  59.                 .getAttribute(CONST_CAS_ASSERTION) : null;   
  60.         final boolean wasGatewayed = session != null  
  61.                 && session.getAttribute(CONST_CAS_GATEWAY) != null;   
  62.         // 如果访问路径为localLoginUrl且带有validated参数则跳过  
  63.         URL url = new URL(localLoginUrl);   
  64.         final boolean isValidatedLocalLoginUrl = request.getRequestURI()   
  65.                 .endsWith(url.getPath())   
  66.                 && CommonUtils.isNotBlank(request.getParameter("validated"));   
  67.            
  68.         if (!isValidatedLocalLoginUrl && CommonUtils.isBlank(ticket)   
  69.                 && assertion == null && !wasGatewayed)   
  70.         {   
  71.             log.debug("no ticket and no assertion found");   
  72.             if (this.gateway)   
  73.             {   
  74.                 log.debug("setting gateway attribute in session");   
  75.                 request.getSession(true).setAttribute(CONST_CAS_GATEWAY, "yes");   
  76.             }   
  77.             final String serviceUrl = constructServiceUrl(request, response);   
  78.             if (log.isDebugEnabled())   
  79.             {   
  80.                 log.debug("Constructed service url: " + serviceUrl);   
  81.             }   
  82.             String urlToRedirectTo = CommonUtils.constructRedirectUrl(   
  83.                     this.casServerLoginUrl, getServiceParameterName(),   
  84.                     serviceUrl, this.renew, this.gateway);   
  85.             // 加入localLoginUrl  
  86.             urlToRedirectTo += (urlToRedirectTo.contains("?") ? "&" : "?")   
  87.                     + "loginUrl=" + URLEncoder.encode(localLoginUrl, "utf-8");   
  88.             if (log.isDebugEnabled())   
  89.             {   
  90.                 log.debug("redirecting to \"" + urlToRedirectTo + "\"");   
  91.             }   
  92.                
  93.             response.sendRedirect(urlToRedirectTo);   
  94.             return;   
  95.         }   
  96.         if (session != null)   
  97.         {   
  98.             log.debug("removing gateway attribute from session");   
  99.             session.setAttribute(CONST_CAS_GATEWAY, null);   
  100.         }   
  101.         filterChain.doFilter(request, response);   
  102.     }   
  103.        
  104.     public final void setRenew(final boolean renew)   
  105.     {   
  106.         this.renew = renew;   
  107.     }   
  108.        
  109.     public final void setGateway(final boolean gateway)   
  110.     {   
  111.         this.gateway = gateway;   
  112.     }   
  113.        
  114.     public final void setCasServerLoginUrl(final String casServerLoginUrl)   
  115.     {   
  116.         this.casServerLoginUrl = casServerLoginUrl;   
  117.     }   
  118.        
  119.     public final void setLocalLoginUrl(String localLoginUrl)   
  120.     {   
  121.         this.localLoginUrl = localLoginUrl;   
  122.     }   
  123.        
  124. }  



2.web.xml中配置:

旧配置

Xml代码 复制代码
  1. <filter>  
  2.         <filter-name>CAS Authentication Filter</filter-name>  
  3.         <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
  4.         <init-param>  
  5.             <param-name>casServerLoginUrl</param-name>  
  6.             <param-value>https://localhost:8443/cas/login</param-value>  
  7.         </init-param>  
  8.         <init-param>  
  9.             <param-name>serverName</param-name>  
  10.             <param-value>http://localhost:8080</param-value>    
  11.         </init-param>  
  12.         <init-param>  
  13.             <param-name>renew</param-name>  
  14.             <param-value>false</param-value>  
  15.         </init-param>  
  16.         <init-param>  
  17.             <param-name>gateway</param-name>  
  18.             <param-value>false</param-value>  
  19.         </init-param>  
  20.     </filter>  


修改成这样,注:其它路径mapping不用改。

Xml代码 复制代码
  1. <filter>  
  2.         <filter-name>CAS Authentication Filter</filter-name>  
  3.         <filter-class>org.demo.user.common.RemoteAuthenticationFilter</filter-class>  
  4.         <init-param>  
  5.             <param-name>localLoginUrl</param-name>  
  6.             <param-value>http://localhost:8080/app/mylogin.jsp</param-value>  
  7.         </init-param>  
  8.         <init-param>  
  9.             <param-name>casServerLoginUrl</param-name>  
  10.             <param-value>https://localhost:8443/cas/remoteLogin</param-value>  
  11.         </init-param>  
  12.         <init-param>  
  13.             <param-name>serverName</param-name>  
  14.             <param-value>http://localhost:8080</param-value>  
  15.         </init-param>  
  16.     </filter>  



3.加上你自己定义的登录界面,注:我修改了一些网上介绍的代码:

Xml代码 复制代码
  1. <%@ page language="java" contentType="text/html; charset=utf-8"  
  2.     pageEncoding="utf-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <head>  
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
  6. <title>APP1客户端登录</title>  
  7. <link rel="stylesheet" type="text/css"  
  8.     href="<%=request.getContextPath()%>/styles/main.css" />  
  9. <script type="text/javascript">  
  10.     function getParam(name)   
  11.     {   
  12.         var queryString = window.location.search;   
  13.         var param = queryString.substr(1, queryString.length - 1).split("&");   
  14.         for (var i = 0; i < param.length; i++)   
  15.         {   
  16.             var keyValue = param[i].split("=");   
  17.             if (keyValue[0] == name)   
  18.                 return keyValue[1];   
  19.         }   
  20.         return null;   
  21.     }   
  22.     function init()   
  23.     {   
  24.         // 显示异常信息   
  25.         var error = getParam("errorMessage");   
  26.         if (error)   
  27.         {   
  28.             document.getElementById("errorMessage").innerHTML = decodeURIComponent(error);   
  29.         }   
  30.            
  31.         // 注入service   
  32.         var service = getParam("service");   
  33.         if (service)   
  34.             document.getElementById("service").value = decodeURIComponent(service);   
  35.         else   
  36.             document.getElementById("service").value = location.href;   
  37.     }   
  38. </script>  
  39. </head>  
  40. <body>  
  41.     <h1>APP1客户端登录</h1>  
  42.   
  43.     <div id="errorMessage" style="color: red;"></div>  
  44.     <form id="myLoginForm" action="https://localhost:8443/cas/remoteLogin?service=http://localhost:8080/app/pages/home.jsp"  
  45.         method="post">  
  46.            
  47.         <input type="hidden" name="loginUrl" value="http://localhost:8080/app/mylogin.jsp">  
  48.         <input type="hidden" name="submit" value="true" />  
  49.         <input type="hidden" name="lt" id="loginTicket" value="" />  
  50.            
  51.         <table>  
  52.             <tr>  
  53.                 <td>用户名:</td>  
  54.                 <td><input type="text" name="username"></td>  
  55.             </tr>  
  56.             <tr>  
  57.                 <td>密&nbsp;&nbsp;码:</td>  
  58.                 <td><input type="password" name="password"></td>  
  59.             </tr>  
  60.             <tr>  
  61.                 <td colspan="2"><input type="submit" value="登陆" /></td>  
  62.             </tr>  
  63.         </table>  
  64.     </form>  
  65.     <script type="text/javascript">  
  66.         init()   
  67.     </script>  
  68. </body>  
  69. </html>  


至此客户端完结!

服务端篇:注我没有加上登出代码,因为登出代码可以使用原有的
1.添加客户端登录Action,org.jasig.cas.web.flow.RemoteLoginAction:

Java代码 复制代码 收藏代码
  1. /**  
  2.  * 远程登陆票据提供Action. 根据InitialFlowSetupAction修改. 
  3.  * 由于InitialFlowSetupAction为final类,因此只能将代码复制过来再进行修改. 
  4.  */  
  5. public class RemoteLoginAction extends AbstractAction   
  6. {   
  7.     /** CookieGenerator for the Warnings. */  
  8.     @NotNull  
  9.     private CookieRetrievingCookieGenerator warnCookieGenerator;   
  10.     /** CookieGenerator for the TicketGrantingTickets. */  
  11.     @NotNull  
  12.     private CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator;   
  13.     /** Extractors for finding the service. */  
  14.     @NotNull  
  15.     @Size(min = 1)   
  16.     private List<ArgumentExtractor> argumentExtractors;   
  17.     /** Boolean to note whether we've set the values on the generators or not. */  
  18.     private boolean pathPopulated = false;   
  19.        
  20.     protected Event doExecute(final RequestContext context) throws Exception   
  21.     {   
  22.         final HttpServletRequest request = WebUtils   
  23.                 .getHttpServletRequest(context);   
  24.         if (!this.pathPopulated)   
  25.         {   
  26.             final String contextPath = context.getExternalContext()   
  27.                     .getContextPath();   
  28.             final String cookiePath = StringUtils.hasText(contextPath) ? contextPath   
  29.                     : "/";   
  30.             logger.info("Setting path for cookies to: " + cookiePath);   
  31.             this.warnCookieGenerator.setCookiePath(cookiePath);   
  32.             this.ticketGrantingTicketCookieGenerator.setCookiePath(cookiePath);   
  33.             this.pathPopulated = true;   
  34.         }   
  35.         context.getFlowScope().put(   
  36.                 "ticketGrantingTicketId",   
  37.                 this.ticketGrantingTicketCookieGenerator   
  38.                         .retrieveCookieValue(request));   
  39.         context.getFlowScope().put(   
  40.                 "warnCookieValue",   
  41.                 Boolean.valueOf(this.warnCookieGenerator   
  42.                         .retrieveCookieValue(request)));   
  43.            
  44.         // 存放service url  
  45.         // context.getFlowScope().put("serviceUrl", request.getParameter("service"));  
  46.            
  47.         final Service service = WebUtils.getService(this.argumentExtractors,   
  48.                 context);   
  49.         if (service != null && logger.isDebugEnabled())   
  50.         {   
  51.             logger.debug("Placing service in FlowScope: " + service.getId());   
  52.         }   
  53.         context.getFlowScope().put("service", service);   
  54.            
  55.         // 客户端必须传递loginUrl参数过来,否则无法确定登陆目标页面  
  56.         if (StringUtils.hasText(request.getParameter("loginUrl")))   
  57.         {   
  58.             context.getFlowScope().put("remoteLoginUrl",   
  59.                     request.getParameter("loginUrl"));   
  60.         } else  
  61.         {   
  62.             request.setAttribute("remoteLoginMessage",   
  63.                     "loginUrl parameter must be supported.");   
  64.             return error();   
  65.         }   
  66.            
  67.         // 若参数包含submit则进行提交,否则进行验证  
  68.         if (StringUtils.hasText(request.getParameter("submit")))   
  69.         {   
  70.             return result("submit");   
  71.         } else  
  72.         {   
  73.             return result("checkTicketGrantingTicket");   
  74.         }   
  75.     }   
  76.        
  77.     public void setTicketGrantingTicketCookieGenerator(   
  78.             final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator)   
  79.     {   
  80.         this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator;   
  81.     }   
  82.        
  83.     public void setWarnCookieGenerator(   
  84.             final CookieRetrievingCookieGenerator warnCookieGenerator)   
  85.     {   
  86.         this.warnCookieGenerator = warnCookieGenerator;   
  87.     }   
  88.        
  89.     public void setArgumentExtractors(   
  90.             final List<ArgumentExtractor> argumentExtractors)   
  91.     {   
  92.         this.argumentExtractors = argumentExtractors;   
  93.     }   
  94. }  



2.重写LoginForm代码,org.jasig.cas.web.flow.AuthenticationViaFormAction重写,此类基本上采用原有代码,只是添加了获取用户名与密码的代码:

Java代码
  1. public class AuthenticationViaFormAction   
  2. {   
  3.     /**  
  4.      * Binder that allows additional binding of form object beyond Spring 
  5.      * defaults.  
  6.      */  
  7.     private CredentialsBinder credentialsBinder;   
  8.        
  9.     /** Core we delegate to for handling all ticket related tasks. */  
  10.     @NotNull  
  11.     private CentralAuthenticationService centralAuthenticationService;   
  12.        
  13.     @NotNull  
  14.     private CookieGenerator warnCookieGenerator;   
  15.        
  16.     protected Logger logger = LoggerFactory.getLogger(getClass());   
  17.        
  18.     public final void doBind(final RequestContext context,   
  19.             final Credentials credentials) throws Exception   
  20.     {   
  21.         final HttpServletRequest request = WebUtils   
  22.                 .getHttpServletRequest(context);   
  23.            
  24.         if (this.credentialsBinder != null  
  25.                 && this.credentialsBinder.supports(credentials.getClass()))   
  26.         {   
  27.             this.credentialsBinder.bind(request, credentials);   
  28.         }   
  29.     }   
  30.        
  31.     public final String submit(final RequestContext context,   
  32.             final MessageContext messageContext) throws Exception   
  33.     {   
  34.         // Validate login ticket  
  35.         final String authoritativeLoginTicket = WebUtils   
  36.                 .getLoginTicketFromFlowScope(context);   
  37.         final String providedLoginTicket = WebUtils   
  38.                 .getLoginTicketFromRequest(context);   
  39.         if (!authoritativeLoginTicket.equals(providedLoginTicket))   
  40.         {   
  41.             this.logger.warn("Invalid login ticket " + providedLoginTicket);   
  42.             final String code = "INVALID_TICKET";   
  43.             messageContext.addMessage(new MessageBuilder().error().code(code)   
  44.                     .arg(providedLoginTicket).defaultText(code).build());   
  45.             return "error";   
  46.         }   
  47.         final String ticketGrantingTicketId = WebUtils   
  48.                 .getTicketGrantingTicketId(context);   
  49.         final Service service = WebUtils.getService(context);   
  50.         final HttpServletRequest request = WebUtils   
  51.                 .getHttpServletRequest(context);   
  52.         org.jasig.cas.authentication.principal.UsernamePasswordCredentials credentials = new org.jasig.cas.authentication.principal.UsernamePasswordCredentials();   
  53.         credentials.setPassword(request.getParameter("password"));   
  54.         credentials.setUsername(request.getParameter("username"));   
  55.         if (StringUtils.hasText(context.getRequestParameters().get("renew"))   
  56.                 && ticketGrantingTicketId != null && service != null)   
  57.         {   
  58.             try  
  59.             {   
  60.                 final String serviceTicketId = this.centralAuthenticationService   
  61.                         .grantServiceTicket(ticketGrantingTicketId, service,   
  62.                                 credentials);   
  63.                 WebUtils.putServiceTicketInRequestScope(context,   
  64.                         serviceTicketId);   
  65.                 putWarnCookieIfRequestParameterPresent(context);   
  66.                 return "warn";   
  67.             } catch (final TicketException e)   
  68.             {   
  69.                 if (e.getCause() != null  
  70.                         && AuthenticationException.class.isAssignableFrom(e   
  71.                                 .getCause().getClass()))   
  72.                 {   
  73.                     populateErrorsInstance(context, e, messageContext);   
  74.                     return "error";   
  75.                 }   
  76.                 this.centralAuthenticationService   
  77.                         .destroyTicketGrantingTicket(ticketGrantingTicketId);   
  78.                 if (logger.isDebugEnabled())   
  79.                 {   
  80.                     logger.debug(   
  81.                             "Attempted to generate a ServiceTicket using renew=true with different credentials",   
  82.                             e);   
  83.                 }   
  84.             }   
  85.         }   
  86.            
  87.         try  
  88.         {   
  89.             WebUtils.putTicketGrantingTicketInRequestScope(context,   
  90.                     this.centralAuthenticationService   
  91.                             .createTicketGrantingTicket(credentials));   
  92.             putWarnCookieIfRequestParameterPresent(context);   
  93.             return "success";   
  94.         } catch (final TicketException e)   
  95.         {   
  96.             populateErrorsInstance(context, e, messageContext);   
  97.             return "error";   
  98.         }   
  99.     }   
  100.        
  101.     public final String submit(final RequestContext context,   
  102.             final Credentials credentials, final MessageContext messageContext)   
  103.             throws Exception   
  104.     {   
  105.         // Validate login ticket  
  106.         final String authoritativeLoginTicket = WebUtils   
  107.                 .getLoginTicketFromFlowScope(context);   
  108.         final String providedLoginTicket = WebUtils   
  109.                 .getLoginTicketFromRequest(context);   
  110.         if (!authoritativeLoginTicket.equals(providedLoginTicket))   
  111.         {   
  112.             this.logger.warn("Invalid login ticket " + providedLoginTicket);   
  113.             final String code = "INVALID_TICKET";   
  114.             messageContext.addMessage(new MessageBuilder().error().code(code)   
  115.                     .arg(providedLoginTicket).defaultText(code).build());   
  116.             return "error";   
  117.         }   
  118.            
  119.         final String ticketGrantingTicketId = WebUtils   
  120.                 .getTicketGrantingTicketId(context);   
  121.         final Service service = WebUtils.getService(context);   
  122.         if (StringUtils.hasText(context.getRequestParameters().get("renew"))   
  123.                 && ticketGrantingTicketId != null && service != null)   
  124.         {   
  125.                
  126.             try  
  127.             {   
  128.                 final String serviceTicketId = this.centralAuthenticationService   
  129.                         .grantServiceTicket(ticketGrantingTicketId, service,   
  130.                                 credentials);   
  131.                 WebUtils.putServiceTicketInRequestScope(context,   
  132.                         serviceTicketId);   
  133.                 putWarnCookieIfRequestParameterPresent(context);   
  134.                 return "warn";   
  135.             } catch (final TicketException e)   
  136.             {   
  137.                 if (isCauseAuthenticationException(e))   
  138.                 {   
  139.                     populateErrorsInstance(e, messageContext);   
  140.                     return getAuthenticationExceptionEventId(e);   
  141.                 }   
  142.                    
  143.                 this.centralAuthenticationService   
  144.                         .destroyTicketGrantingTicket(ticketGrantingTicketId);   
  145.                 if (logger.isDebugEnabled())   
  146.                 {   
  147.                     logger.debug(   
  148.                             "Attempted to generate a ServiceTicket using renew=true with different credentials",   
  149.                             e);   
  150.                 }   
  151.             }   
  152.         }   
  153.            
  154.         try  
  155.         {   
  156.             WebUtils.putTicketGrantingTicketInRequestScope(context,   
  157.                     this.centralAuthenticationService   
  158.                             .createTicketGrantingTicket(credentials));   
  159.             putWarnCookieIfRequestParameterPresent(context);   
  160.             return "success";   
  161.         } catch (final TicketException e)   
  162.         {   
  163.             populateErrorsInstance(e, messageContext);   
  164.             if (isCauseAuthenticationException(e))   
  165.                 return getAuthenticationExceptionEventId(e);   
  166.             return "error";   
  167.         }   
  168.     }   
  169.        
  170.     private void populateErrorsInstance(final TicketException e,   
  171.             final MessageContext messageContext)   
  172.     {   
  173.            
  174.         try  
  175.         {   
  176.             messageContext.addMessage(new MessageBuilder().error()   
  177.                     .code(e.getCode()).defaultText(e.getCode()).build());   
  178.         } catch (final Exception fe)   
  179.         {   
  180.             logger.error(fe.getMessage(), fe);   
  181.         }   
  182.     }   
  183.        
  184.     private void populateErrorsInstance(final RequestContext context,   
  185.             final TicketException e, final MessageContext messageContext)   
  186.     {   
  187.            
  188.         try  
  189.         {   
  190.             messageContext.addMessage(new MessageBuilder().error()   
  191.                     .code(e.getCode()).defaultText(e.getCode()).build());   
  192.                
  193.             Message[] messages = messageContext.getAllMessages();   
  194.                
  195.             context.getFlowScope().put("remoteLoginMessage",   
  196.                     messages[messages.length - 1].getText());   
  197.                
  198.         } catch (final Exception fe)   
  199.         {   
  200.             logger.error(fe.getMessage(), fe);   
  201.         }   
  202.     }   
  203.        
  204.     private void putWarnCookieIfRequestParameterPresent(   
  205.             final RequestContext context)   
  206.     {   
  207.         final HttpServletResponse response = WebUtils   
  208.                 .getHttpServletResponse(context);   
  209.            
  210.         if (StringUtils.hasText(context.getExternalContext()   
  211.                 .getRequestParameterMap().get("warn")))   
  212.         {   
  213.             this.warnCookieGenerator.addCookie(response, "true");   
  214.         } else  
  215.         {   
  216.             this.warnCookieGenerator.removeCookie(response);   
  217.         }   
  218.     }   
  219.        
  220.     private AuthenticationException getAuthenticationExceptionAsCause(   
  221.             final TicketException e)   
  222.     {   
  223.         return (AuthenticationException) e.getCause();   
  224.     }   
  225.        
  226.     private String getAuthenticationExceptionEventId(final TicketException e)   
  227.     {   
  228.         final AuthenticationException authEx = getAuthenticationExceptionAsCause(e);   
  229.            
  230.         if (this.logger.isDebugEnabled())   
  231.             this.logger   
  232.                     .debug("An authentication error has occurred. Returning the event id "  
  233.                             + authEx.getType());   
  234.            
  235.         return authEx.getType();   
  236.     }   
  237.        
  238.     private boolean isCauseAuthenticationException(final TicketException e)   
  239.     {   
  240.         return e.getCause() != null  
  241.                 && AuthenticationException.class.isAssignableFrom(e.getCause()   
  242.                         .getClass());   
  243.     }   
  244.        
  245.     public final void setCentralAuthenticationService(   
  246.             final CentralAuthenticationService centralAuthenticationService)   
  247.     {   
  248.         this.centralAuthenticationService = centralAuthenticationService;   
  249.     }   
  250.        
  251.     /**  
  252.      * Set a CredentialsBinder for additional binding of the HttpServletRequest 
  253.      * to the Credentials instance, beyond our default binding of the 
  254.      * Credentials as a Form Object in Spring WebMVC parlance. By the time we 
  255.      * invoke this CredentialsBinder, we have already engaged in default binding 
  256.      * such that for each HttpServletRequest parameter, if there was a JavaBean 
  257.      * property of the Credentials implementation of the same name, we have set 
  258.      * that property to be the value of the corresponding request parameter. 
  259.      * This CredentialsBinder plugin point exists to allow consideration of 
  260.      * things other than HttpServletRequest parameters in populating the 
  261.      * Credentials (or more sophisticated consideration of the 
  262.      * HttpServletRequest parameters). 
  263.      *   
  264.      * @param credentialsBinder 
  265.      *            the credentials binder to set. 
  266.      */  
  267.     public final void setCredentialsBinder(   
  268.             final CredentialsBinder credentialsBinder)   
  269.     {   
  270.         this.credentialsBinder = credentialsBinder;   
  271.     }   
  272.        
  273.     public final void setWarnCookieGenerator(   
  274.             final CookieGenerator warnCookieGenerator)   
  275.     {   
  276.         this.warnCookieGenerator = warnCookieGenerator;   
  277.     }   
  278. }  



3.web.xml配置,原有基础上新增这两句:

Xml代码
  1. <servlet-mapping>  
  2.      <servlet-name>cas</servlet-name>  
  3.      <url-pattern>/remoteLogin</url-pattern>  
  4.  </servlet-mapping>  



4.在cas-servlet.xml中最后面增加以下信息:

Xml代码
  1. <bean id="handlerMappingB"  
  2.         class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
  3.         <property name="mappings">  
  4.             <props>  
  5.                 <prop key="/remoteLogin">remoteLoginController</prop>  
  6.             </props>  
  7.         </property>  
  8.         <property name="interceptors">  
  9.             <list>  
  10.                 <ref bean="localeChangeInterceptor" />  
  11.             </list>  
  12.         </property>  
  13.     </bean>  
  14.   
  15.     <bean id="remoteLoginController" class="org.springframework.webflow.mvc.servlet.FlowController">  
  16.         <property name="flowExecutor" ref="remoteLoginFlowExecutor" />  
  17.         <property name="flowUrlHandler" ref="flowUrlHandler" />  
  18.     </bean>  
  19.   
  20.     <webflow:flow-executor id="remoteLoginFlowExecutor"  
  21.         flow-registry="remoteLoginFlowRegistry">  
  22.         <webflow:flow-execution-attributes>  
  23.             <webflow:always-redirect-on-pause  
  24.                 value="false" />  
  25.         </webflow:flow-execution-attributes>  
  26.     </webflow:flow-executor>  
  27.   
  28.     <webflow:flow-registry id="remoteLoginFlowRegistry"  
  29.         flow-builder-services="builder">  
  30.         <webflow:flow-location path="/WEB-INF/remoteLogin-webflow.xml"  
  31.             id="remoteLogin" />  
  32.     </webflow:flow-registry>  
  33.   
  34.     <webflow:flow-builder-services id="flowBuilderServices"  
  35.         view-factory-creator="viewFactoryCreator" />  
  36.   
  37.     <bean id="remoteLoginAction" class="org.jasig.cas.web.flow.RemoteLoginAction"  
  38.         p:argumentExtractors-ref="argumentExtractors"  
  39.         p:warnCookieGenerator-ref="warnCookieGenerator"  
  40.         p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator" />  
  41.   
  42.     <bean id="remoteLogoutController" class="org.springframework.webflow.mvc.servlet.FlowController">  
  43.         <property name="flowExecutor" ref="remoteLogoutFlowExecutor" />  
  44.         <property name="flowUrlHandler" ref="flowUrlHandler" />  
  45.     </bean>  



5.新建一个文件与login-webflow.xml同级,remoteLogin-webflow.xml:

Xml代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <flow xmlns="http://www.springframework.org/schema/webflow"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/webflow   
  5.                           http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"   
  6.     start-state="remoteLogin">  
  7.        
  8.     <!-- <on-start> <evaluate expression="remoteLoginAction.doBind(flowRequestContext,    
  9.         flowScope.credentials)" /> </on-start> -->  
  10.     <var name="credentials"  
  11.         class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" />  
  12.            
  13.     <!-- 远程登陆主要Action -->  
  14.     <action-state id="remoteLogin">  
  15.         <evaluate expression="remoteLoginAction" />  
  16.         <transition on="error" to="remoteCallbackView" />  
  17.         <transition on="submit" to="bindAndValidate" />  
  18.         <transition on="checkTicketGrantingTicket" to="ticketGrantingTicketExistsCheck" />  
  19.     </action-state>  
  20.   
  21.     <!-- 远程回调页面,主要以JavaScript的方式回传一些参数用 -->  
  22.     <end-state id="remoteCallbackView" view="remoteCallbackView" />  
  23.   
  24.     <action-state id="bindAndValidate">  
  25.         <evaluate  
  26.             expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />  
  27.         <transition on="success" to="submit" />  
  28.         <transition on="error" to="remoteCallbackView" />  
  29.     </action-state>  
  30.   
  31.     <decision-state id="ticketGrantingTicketExistsCheck">  
  32.         <if test="flowScope.ticketGrantingTicketId != null" then="hasServiceCheck"  
  33.             else="gatewayRequestCheck" />  
  34.     </decision-state>  
  35.   
  36.     <decision-state id="hasServiceCheck">  
  37.         <if test="flowScope.service != null" then="generateServiceTicket"  
  38.             else="remoteCallbackView" />  
  39.     </decision-state>  
  40.     <decision-state id="gatewayRequestCheck">  
  41.         <if  
  42.             test="externalContext.requestParameterMap['gateway'] neq '' &amp;&amp; externalContext.requestParameterMap['gateway'] neq null &amp;&amp; flowScope.service neq null"  
  43.             then="redirect" else="remoteCallbackView" />  
  44.     </decision-state>  
  45.   
  46.     <action-state id="generateServiceTicket">  
  47.         <evaluate expression="generateServiceTicketAction" />  
  48.         <transition on="success" to="warn" />  
  49.         <transition on="error" to="remoteCallbackView" />  
  50.         <transition on="gateway" to="redirect" />  
  51.     </action-state>  
  52.   
  53.     <decision-state id="warn">  
  54.         <if test="flowScope.warnCookieValue" then="showWarningView" else="redirect" />  
  55.     </decision-state>  
  56.   
  57.     <action-state id="submit">  
  58.         <evaluate  
  59.             expression="authenticationViaFormAction.submit(flowRequestContext, messageContext)" />  
  60.         <transition on="warn" to="warn" />  
  61.         <transition on="success" to="sendTicketGrantingTicket" />  
  62.         <transition on="error" to="remoteCallbackView" />  
  63.     </action-state>  
  64.   
  65.     <action-state id="sendTicketGrantingTicket">  
  66.         <evaluate expression="sendTicketGrantingTicketAction" />  
  67.         <transition to="serviceCheck" />  
  68.     </action-state>  
  69.   
  70.     <decision-state id="serviceCheck">  
  71.         <if test="flowScope.service neq null" then="generateServiceTicket"  
  72.             else="remoteCallbackView" />  
  73.     </decision-state>  
  74.   
  75.     <end-state id="showWarningView" view="casLoginConfirmView" />  
  76.   
  77.     <!-- <end-state id="redirect" view="bean:dynamicRedirectViewSelector" /> -->  
  78.   
  79.     <action-state id="redirect">  
  80.         <evaluate  
  81.             expression="flowScope.service.getResponse(requestScope.serviceTicketId)"  
  82.             result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response" />  
  83.         <transition to="postRedirectDecision" />  
  84.     </action-state>  
  85.   
  86.     <decision-state id="postRedirectDecision">  
  87.         <if test="requestScope.response.responseType.name() eq 'POST'"  
  88.             then="postView" else="redirectView" />  
  89.     </decision-state>  
  90.        
  91.     <!-- <decision-state id="hashServiceUrl">  
  92.         <if test="flowScope.serviceUrl neq null" then="redirectServiceView"  else="redirectView"/>  
  93.     </decision-state>  
  94.     <end-state id="redirectServiceView" view="externalRedirect:${flowScope.serviceUrl}" /> -->  
  95.        
  96.     <end-state id="postView" view="postResponseView">  
  97.         <on-entry>  
  98.             <set name="requestScope.parameters" value="requestScope.response.attributes" />  
  99.             <set name="requestScope.originalUrl" value="flowScope.service.id" />  
  100.         </on-entry>  
  101.     </end-state>  
  102.     <end-state id="redirectView" view="externalRedirect:${requestScope.response.url}" />  
  103.   
  104.     <end-state id="viewServiceErrorView" view="viewServiceErrorView" />  
  105.     <end-state id="viewServiceSsoErrorView" view="viewServiceSsoErrorView" />  
  106.   
  107.     <global-transitions>  
  108.         <transition to="viewServiceErrorView"  
  109.             on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException" />  
  110.         <transition to="viewServiceSsoErrorView"  
  111.             on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException" />  
  112.         <transition to="viewServiceErrorView"  
  113.             on-exception="org.jasig.cas.services.UnauthorizedServiceException" />  
  114.     </global-transitions>  
  115. </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:

Java代码
  1. <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>   
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>   
  3. <%-- <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>   
  4. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> --%>   
  5. <script type="text/javascript">   
  6.     var remoteUrl = "${remoteLoginUrl}?validated=true";   
  7.     // 构造错误消息,从webflow scope中取出  
  8.     var errorMessage = '${remoteLoginMessage}';   
  9.     /* <spring:hasBindErrors name="credentials"> 
  10.      errorMessage = "&errorMessage=" + encodeURIComponent('<c:forEach var="error" items="${errors.allErrors}"><spring:message code="${error.code}" text="${error.defaultMessage}" /></c:forEach>'); 
  11.     </spring:hasBindErrors> */  
  12.     // 如果存在错误消息则追加到 url中  
  13.     if(null != errorMessage && errorMessage.length > 0)   
  14.     {   
  15.         errorMessage = "&errorMessage=" + encodeURIComponent(errorMessage);   
  16.     }   
  17.     // 构造service  
  18.     var service = "";   
  19.     <c:if test="${service != null && service != ''}">   
  20.      service = "&service=" + encodeURIComponent("${service}");   
  21.     </c:if>   
  22.        
  23.     // 跳转回去(客户端)  
  24.     window.location.href = remoteUrl + errorMessage + service;   
  25. </script>  

 

1 0
原创粉丝点击