让CAS支持客户端自定义登陆页面——服务器篇- [De velopment]
2009-03-23
声明 时请以超形式标明文章原始出处和作者信息及本声明fallenlord.blogbus./logs/36907044.html
上篇《让CAS支持客户端自定义登陆页面——原理篇》讲述了一些修改的理论基础这篇讲解如何对C AS服务器端进行修改。
修改需要基于几个基本原则
1 . 不影响原有统一登陆界面功能
2. 客户端应尽量保持简单
3. 尽量保证原有功能的完整性和安全性
对于第三点 必须事先说明将登陆页面放到客户端本身就是降低了 CAS安全性这意味着作为服务向外发布的CAS服务器中的用户密码有可能由于客户端的不安全性而导致泄露整个CAS系统成为了一个“水桶形态”整个CAS体系的安全性将取决于所有客户端中安全性最低的一个。这也是CAS官方一直不推荐的方式。
接下来我们讲解服务器端修改的详细过程
首先修改/WEB-IN F/web.xml 为cas增加一个/remoteLogin的映射
<servl et-mappi ng>
<servlet-n ame>c as</s ervlet-n ame>
<url-pattern>/remoteLogin</url-pattern>
</servl et-mapping>
然后修改cas-servlet.xml文件 增加我们对/remoteLogin映射的处理 需要增加一个新流程<bean id="handlerMappingB" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMappi ng ">
<property name="mappings">
<props>
<prop key="/login">loginControl ler</prop>
<prop key="/remoteLogin">remoteControl ler</prop>
</props>
</property>
<property name="interceptors">
<l ist>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</b ea n>
然后在cas-servlet.xml文件中添加我们上面所配置的remoteController的bean
<!--增加远程控制者 允许以/remote请求启动remote控制流程-->
<bean id="remoteLoginControl ler"class="org.springframework.webflow.executor.mvc.FlowController"p:flowExecutor-ref="remoteLoginFlowExecutor"p:defaultFlowId="remoteLogin-webflow">
<property name="argumentHandl er">
<bean class="org.springframework.webflow.executor.support.RequestParameterFlowExecutorArgumentHandler"p:flowExecutionKeyArgu mentName="lt"
p:defaultFlowId="remoteLogin-webflow" />
</property>
</b ea n>
<flow:executor id="remoteLoginFlowExecutor" registry-ref="remoteLoginFlowRegistry">
<flow:execution-attributes>
<flow:alwaysRedirectOnPause value="false"/>
</flow:execution-attributes>
</flow:executor>
<flow:registry id="remoteLoginFlowRegistry">
<flow:location path="/WEB-INF/remoteLogin-webflow.xml"/>
</flow:registry>
可以看到上面将请求指向了webflow配置文件/WEB-IN F/remoteLogin-webflow.xml文件 我们需要创建此文件并配置其成为我们所需的流程 以下是remoteLogin-webflow.xml全文
<?xml version="1 .0" encoding="UTF-8"?>
<flow xmlns=".springframework.org/schema/webflow"xmlns:xsi=".w3.org/2001/XMLSchema-instance"xsi :schemaLocation="
.springframework.org/schema/webflow
.springframework.org/schema/webflow/spring-webflow-1 .0.xsd">
<start-state idref="remoteLogin"/>
<!--远程登陆主要Action -->
<action-state id="remoteLogin">
<action bean="remoteLoginAction" />
<transition on="error" to="remoteCal lbackView" />
<transition on="submit" to="bindAndValidate" />
<transition on="checkTicketGrantingTicket" to="ticketGrantingTicketExistsCheck" />
</action-state>
<!--远程回调页面 主要以JavaScript的方式回传一些参数用 -->
<end-state id="remoteCal lbackView" view="remoteCallbackView" />
<decision-state id="ticketGrantingTicketExistsCheck">
<if test="${flowScope.ticketGrantingTicketId != nul l}" then="hasServiceCheck"else="gat ewayRequ estCh eck" />
</decision-state>
<decision-state id="gatewayRequestCheck">
<if test="${external Context.requestParameterMap['gateway'] != ''&& externalContext.re questParameterMap['gateway'] != null&& flowScope.service != nul l}" then="redirect" else="re moteCal lbackView" />
</decision-state>
<decision-state id="hasServiceCheck">
<if test="${flowScope.service != nul l}" then="generateServiceTicket" else="remoteCal lbackView"/>
</decision-state>
<!--
The "warn" action makes the determination of whether to redirect directly to the requested service or display the "confirmation" page to go back to the server.
-->
<decision-state id="warn">
<if test="${flowScope.warnCookieValue}" then="showWarningView" else="redirect" /></decision-state>
<action-state id="bindAndVal idate">
<action bean="authenticationViaFormAction" />
<transition on="success" to="submit" />
<transition on="error" to="remoteCal lbackView" />
</action-state>
<action-state id="submit">
<action bean="authenticationViaFormAction"method="submit" />
<transition on="warn" to="warn" />
<transition on="success" to="sendTicketGrantingTicket" />
<transition on="error" to="remoteCal lbackView" />
</action-state>
<action-state id="sendTicketGrantingTicket">
<action bean="sendTicketGrantingTicketAction" />
<transition on="success" to="serviceCheck" />
</action-state>
<decision-state id="serviceCheck">
<if test="${flowScope.service != nul l}" then="generateServiceTicket"else="remoteCal lbackView" />
</decision-state>
<action-state id="generateServiceTicket">
<action bean="generateServiceTicketAction" />
<transition on="success" to ="warn" />
<transition on="error" to="remoteCal lbackView" />
<transition on="gateway" to="redirect" />
</action-state>
<!--
The "showWarningView" end state is the end state for when the user has requested privacy settings (to be "warned") to be turned on. It delegates to a view defines in default_views.properties that display the "Please cl ick here to go to the service."message.
-->
<end-state id="showWarningView" view="casLoginConfirmView" />
<!--
The "redirect" end state al lows CAS to properly end the workflow whi le sti l l redirecting the user back to the service required.
-->
<end-state id="redirect" view="bean:dynamicRedirectViewSelector" />
<end-state id="viewServiceErrorView" view="viewServiceErrorView" />
<end-state id="viewServiceSsoErrorView" view="viewServiceSsoErrorView" />
<global-transitions>
<transition to="viewServiceErrorView" on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecuti onException" />
<transition to="viewServiceSsoErrorView" on-
exception="org.jasig.cas.services.UnauthorizedSsoServiceException" />
<transition to="viewServiceErrorView" on-exception="org.jasig.cas.services.UnauthorizedServiceException" />
</global-transitions>
</flow>
以上文件根据原login-webflow.xml文件修改黄色背景为修改部分。可以看到我们在流程中增加了 r emoteLogin Action节点和remoteCallback View节点 下面我们配置remoteLogin节点
在/WEB-IN F/cas-servlet.xml文件中增加remoteLoginAction配置
<bean id="remoteLoginAction"class=".baidu.cas.web.flow.RemoteLoginAction"p:argu mentExtractors-ref="argumentExtractors"p:warnCookieGenerator-ref="warnCookieGenerator"p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator" />
同时创建com.baidu.cas.web.flow.RemoteLoginAction类
*
*远程登陆票据提供Action.
*根据InitialFlowSetupAction修改.
* 由于InitialFlowSetupAction为final类 因此只能将代码复制过来再进行修改.
*
* author GuoLin
*/publ ic class RemoteLoginAction extends AbstractAction {
/** CookieGenerator for the Warnings. */
NotNul l
private CookieRetrievingCookieGenerator warnCookieGenerator;
/** CookieGenerator for the TicketGrantingTickets. */
NotNul l private CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator;/** Extractors for finding the service. */
NotEmpty 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 =WebUti ls.getHttpServletRequest(context);if (!this.pathPo pul ated) {final String contextPath = context.getExternal Context().getContextPath() ;final String cookiePath = StringUti ls.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))) ;final Service service =WebUti ls.getService(this.argumentExtractors, context);if (service != nul l &&logger.isDebugEnabled()) {logger.debug("Placing service in FlowScope: " + service.getId());
}context.getFlowScope().put("service", service) ;
//客户端必须传递loginUrl参数过来否则无法确定登陆目标页面if (StringUti ls.hasText(request.getParameter("loginUrl"))) {context.getFlowScope().put("remoteLoginUrl", request.getParameter("loginUrl"));
} else {request.setAttribute("remoteLoginMessage", "loginUrl parameter must be supported.") ;return error();
}
//若参数包含submit则进行提交否则进行验证if (StringUti ls.hasText(request.getParameter("submit"))) {return result("submit");
} else {return result("checkTicketGrantingTicket");
}
}publ ic void setTicketGrantingTicketCookieGenerator(final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator) {this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator;
}publ ic void setWarnCookieGenerator(final CookieRetrievingCookieGenerator warnCookieGenerator) {this.warnCookieGenerator =warnCookieGenerator;
}publ ic void setArgumentExtractors(
华为云怎么样?华为云用在线的方式将华为30多年在ICT基础设施领域的技术积累和产品解决方案开放给客户,致力于提供稳定可靠、安全可信、可持续创新的云服务,做智能世界的“黑土地”,推进实现“用得起、用得好、用得放心”的普惠AI。华为云作为底座,为华为全栈全场景AI战略提供强大的算力平台和更易用的开发平台。本次年终聚惠618活动相当给力,1核2G内存1m云耀云服务器仅88元/年起,送主机安全基础版套餐,...
企鹅小屋:垃圾服务商有跑路风险!企鹅不允许你二次工单的,二次提交工单直接关服务器,再严重就封号,意思是你提交工单要小心,别因为提交工单被干了账号!前段时间,就有站长说企鹅小屋要跑路了,站长不太相信,本站平台已经为企鹅小屋推荐了几千元的业绩,CPS返利达182.67CNY。然后,站长通过企鹅小屋后台申请提现,提现申请至今已经有20几天,企鹅小屋也没有转账。然后,搞笑的一幕出现了:平台账号登录不上提示...
pacificrack发布了7月最新vps优惠,新款促销便宜vps采用的是魔方管理,也就是PR-M系列。提一下有意思的是这次支持Windows server 2003、2008R2、2012R2、2016、2019、Windows 7、Windows 10,当然啦,常规Linux系统是必不可少的!1Gbps带宽、KVM虚拟、纯SSD raid10、自家QN机房洛杉矶数据中心...支持PayPal、...