让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(
台湾云服务器去哪里买?国内有没有哪里的台湾云服务器这块做的比较好的?有很多用户想用台湾云服务器,那么判断哪家台湾云服务器好,不是按照最便宜或最贵的选择,而是根据您的实际使用目的选择服务器,只有最适合您的才是最好的。总体而言,台湾云服务器的稳定性确实要好于大陆。今天,云服务器网(yuntue.com)小编来介绍一下台湾云服务器哪里买和一年需要多少钱!一、UCloud台湾云服务器UCloud上市云商,...
提速啦的来历提速啦是 网站 本着“良心 便宜 稳定”的初衷 为小白用户避免被坑 由赣州王成璟网络科技有限公司旗下赣州提速啦网络科技有限公司运营 投资1000万人民币 在美国Cera 香港CTG 香港Cera 国内 杭州 宿迁 浙江 赣州 南昌 大连 辽宁 扬州 等地区建立数据中心 正规持有IDC ISP CDN 云牌照 公司。公司购买产品支持3天内退款 超过3天步退款政策。提速啦的市场定位提速啦主...
Nocser刚刚在WHT发布了几款促销服务器,Intel Xeon X3430,8GB内存,1TB HDD,30M不限流量,月付$60.00。Nocser是一家注册于马来西亚的主机商,主要经营虚拟主机、VPS和马来西亚独立服务器业务,数据中心位于马来西亚AIMS机房,线路方面,AIMS到国内电信一般,绕日本NTT;联通和移动比较友好,联通走新加坡,移动走香港,延迟都在100左右。促销马来西亚服务器...