- 浏览: 345150 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
AspirantHui:
楼主说的很有道理。只是你第二点里面写的“行业经验”具体是指什么 ...
一起来讨论程序员的跳槽与选择 -
di1984HIT:
写的不错啊、
linux下的mysql的导入导出命令 -
王迎宾:
① 弄啥来!
MyEclipse配置WebService六步曲(xfire) -
xiaoji123pt:
不错。。
tomcat下catalina.out日志文件分割 -
Unmi:
可是原来那个 catalina.out 文件还是一直保留着老的 ...
tomcat下使用cronolog对catalina.out日志文件分割
这篇讲解如何对CAS服务器端进行修改。
修改需要基于几个基本原则:
- 不影响原有统一登陆界面功能
- 客户端应尽量保持简单
- 尽量保证原有功能的完整性和安全性
对于第三点,必须事先说明:将登陆页面放到客户端本身就是降低了CAS安全性,这意味着作为服务向外发布的CAS服务器中的用户密码有可能由于客户端的不安全性而导致泄露,整个CAS系统成为了一个“水桶形态”,整个CAS体系的安全性将取决于所有客户端中安全性最低的一个。这也是CAS官方一直不推荐的方式。
接下来我们讲解服务器端修改的详细过程:
首先,修改/WEB-INF/web.xml,为cas增加一个/remoteLogin的映射:
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/remoteLogin</url-pattern>
</servlet-mapping>
然后修改cas-servlet.xml文件,增加我们对/remoteLogin映射的处理,需要增加一个新流程:
<bean id="handlerMappingB" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/login">loginController</prop>
<prop key="/remoteLogin">remoteLoginController</prop>
</props>
</property>
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
然后在cas-servlet.xml文件中添加我们上面所配置的remoteController的bean:
<!-- 增加远程控制者,允许以/remote请求启动remote控制流程 -->
<bean id="remoteLoginController"
class="org.springframework.webflow.executor.mvc.FlowController"
p:flowExecutor-ref="remoteLoginFlowExecutor"
p:defaultFlowId="remoteLogin-webflow">
<property name="argumentHandler">
<bean
class="org.springframework.webflow.executor.support.RequestParameterFlowExecutorArgumentHandler"
p:flowExecutionKeyArgumentName="lt"
p:defaultFlowId="remoteLogin-webflow" />
</property>
</bean>
<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-INF/remoteLogin-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-1.0.xsd">
<start-state idref="remoteLogin"/>
<!-- 远程登陆主要Action -->
<action-state id="remoteLogin">
<action bean="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" />
<decision-state id="ticketGrantingTicketExistsCheck">
<if test="${flowScope.ticketGrantingTicketId != null}" then="hasServiceCheck"
else="gatewayRequestCheck" />
</decision-state>
<decision-state id="gatewayRequestCheck">
<if test="${externalContext.requestParameterMap['gateway'] != '' && externalContext.requestParameterMap['gateway'] != null && flowScope.service != null}" then="redirect" else="remoteCallbackView" />
</decision-state>
<decision-state id="hasServiceCheck">
<if test="${flowScope.service != null}" then="generateServiceTicket" else="remoteCallbackView" />
</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="bindAndValidate">
<action bean="authenticationViaFormAction" />
<transition on="success" to="submit" />
<transition on="error" to="remoteCallbackView" />
</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="remoteCallbackView" />
</action-state>
<action-state id="sendTicketGrantingTicket">
<action bean="sendTicketGrantingTicketAction" />
<transition on="success" to="serviceCheck" />
</action-state>
<decision-state id="serviceCheck">
<if test="${flowScope.service != null}" then="generateServiceTicket"
else="remoteCallbackView" />
</decision-state>
<action-state id="generateServiceTicket">
<action bean="generateServiceTicketAction" />
<transition on="success" to ="warn" />
<transition on="error" to="remoteCallbackView" />
<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 click here to go
to the service." message.
-->
<end-state id="showWarningView" view="casLoginConfirmView" />
<!--
The "redirect" end state allows CAS to properly end the workflow while still
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.NoSuchFlowExecutionException" /
>
<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文件修改,粗体为修改部分。可以看到,我们在流程中增加了remoteLogin Action节点和remoteCallback View节点,下面我们配置remoteLogin节点:
在/WEB-INF/cas-servlet.xml文件中增加remoteLoginAction配置:
<bean id="remoteLoginAction"
class="com.baidu.cas.web.flow.RemoteLoginAction"
p:argumentExtractors-ref="argumentExtractors"
p:warnCookieGenerator-ref="warnCookieGenerator"
p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator" />
同时创建com.baidu.cas.web.flow.RemoteLoginAction类:
/**
* 远程登陆票据提供Action.
* 根据InitialFlowSetupAction修改.
* 由于InitialFlowSetupAction为final类,因此只能将代码复制过来再进行修改.
*
* @author GuoLin
*/
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. */
@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 = 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)));
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;
}
}
以上粗体为修改部分,要求客户端必须传入loginUrl参数,且当客户端传入submit参数时,直接为其提交用户名密码
然后再配置remoteCallbackView显示节点,修改src/default_views.properties文件,增加remoteCallbackView配置:
### 配置远程回调页面
remoteCallbackView.(class)=org.springframework.web.servlet.view.JstlView
remoteCallbackView.url=/WEB-INF/view/jsp/default/ui/remoteCallbackView.jsp
创建/WEB-INF/view/jsp/default/ui/remoteCallbackView.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"%>
<html>
<head>
<script type="text/javascript">
var remoteUrl = "${remoteLoginUrl}?validated=true";
// 构造错误消息
var errorMessage = "";
<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>
// 构造service
var service = "";
<c:if test="${service != null && service != ''}">
service = "&service=" + encodeURIComponent("${service}");
</c:if>
// 跳转回去
window.location.href = remoteUrl + errorMessage + service;
</script>
</head>
<body>
${remoteLoginMessage}
</body>
</html>
以上文件注意粗体部分validated=true,这里我们与客户端约定,当客户端登陆页面后带有参数validated=true时,不进行票据认证请求。这是因为,客户端登陆页面为http://clienthost/login.jsp,那么当用户访问URL http://clienthost/login.jsp时,客户端会重定向到CAS中央服务器请求TGT认证,但认证失败后CAS中央认证服务器会重定向到客户端登陆页面并显示登陆框,此时客户端必须以某种规则避免重新请求中央认证服务器认证, 在这里我们与客户端约定,当回发的请求为登陆页面且带有参数validated=true时即不转发TGT认证请求,即 http://
clienthost/login.jsp?validated=true 请求客户端不会重新发送TGT认证请求给中央认证服务器
发表评论
-
mysql8降级使用sql
2020-03-25 13:30 313使用navicate12运行sql文件出错 报错: ... -
在freemarker中获取当前日期及时间比较
2015-09-15 18:39 8576在freemarker中获取当前日期:${.now}获取当前日 ... -
Spring MVC拦截器+注解方式实现防止表单重复提交
2015-07-02 09:03 847原理:在新建页面中Session保存token随机码,当保存 ... -
获取复利总收入
2015-03-08 17:51 785public static void main ... -
使用Spring进行统一日志管理 + 统一异常管理
2015-03-01 23:10 5036统一日志和异常管理配置好后,SSH项目中,代码以往散落的lo ... -
spring3.0异常处理进阶
2015-03-01 23:03 1446spring3.0开发不可避免要遇到异常处理,如果只有jsp ... -
jdk-6u26-linux-x64.bin 安装
2014-05-10 09:14 21581.上传安装文件(jdk-6u26-linux-x64.bi ... -
上一页 下一页SQL语句
2013-11-21 11:46 996上一页 下一页SQL语句 string pr ... -
JDK安装配置 1.7
2013-09-06 07:43 1121JDK安装配置 1、 下载jdk,本例使用jdk-7u5 ... -
java截取中英文混合字符串 等宽显示
2013-09-04 20:44 1718Java代码 import java. ... -
Spring自带html标签转义与反转义
2012-10-10 13:52 5306String ss = "<br>< ... -
ajax与java配合转码方式
2012-10-09 11:47 918(1) 客户端对url进行两次转码:(str可能是中文) J ... -
url的不同获取方式
2012-08-05 16:57 948假定你的web application 名 ... -
推荐两个非常好用的测试工具jmeter和badboy
2011-12-23 10:56 1630loadruner就不用说了,测 ... -
做网站用UTF-8还是GB2312?
2011-12-13 12:15 859经常我们打开外国网站的时候出现乱码,又或者打开很多非英语的外国 ... -
JFreeChart饼状图显示百分比
2011-11-29 15:28 1986jfreechart-1.0.1中设置饼图默认的Label是传 ... -
简单的java加密解密类
2011-11-08 15:19 1861import java.security.Key; impo ... -
利用JDBC获得INSERT插入后生成的主键ID
2011-11-05 17:27 1766ps = conn.prepareStatement(&quo ... -
tomcat下catalina.out日志文件分割
2011-10-31 12:34 1314使用log4j成功使catalina.out文件实现分割。 在 ... -
一步步构建大型网站架构
2011-10-08 16:17 790之前我简单向大家介绍 ...
相关推荐
让CAS支持客户端自定义登陆页面——服务器篇[参考].pdf
让CAS支持客户端自定义登陆页面——服务器篇.docx
NULL 博文链接:https://yeminping.iteye.com/blog/411742
让CAS支持客户端自定义登陆页面----服务器篇--.doc
让CAS支持客户端自定义登陆页面----服务器篇.doc
让CAS支持客户端自定义登陆页面----服务器篇-.pdf
让CAS支持客户端自定义登陆页面----服务器篇--.doc
CAS客户端自定义核心过滤器,继承CAS的AbstractCasFilter自定义AuthenticationFilter
详细描述了cas 自定义登陆页面的配置与demo
cas客户端登录配置详细文档,支持客户端自定义登录和服务端统一登录。
包含cas源码、cas使用说明文档(包含配置信息)、连接数据库所需jar包、cas服务端自定义返回值等
这是boot2.0+shiro+pac4j+cas 整合项目 cas还可以自定义登陆页和认证校验数据库
NULL 博文链接:https://kennylee26.iteye.com/blog/868820
cas4.2.7服务端+cas客户端+示例程序+环境搭建之客户端war包 一切跑不起来的程序和走不通的教程都是耍流氓,二话不说,先按照我的步骤把程序跑起来在说吧。 请看博客...
cas .net客户端的配置代码 CAS 与_net 集成的 “循环重定向”问题分析 - 邢少 - 博客园.mht根本不行的。 我自己另外找的一段代码
CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。 邮箱 erp oa 有一个特点 就是密码和用户名 单点登录 客户端到服务端 1首先要有一...
单点登录CAS.net客户端源码,已调试成功,需要在webconfig中将服务端地址以及跳转地址修改好即可
cas的客户端cas的客户端cas的客户端cas的客户端cas的客户端cas的客户端
这个的注意说明写的比较清除,以这个为...cas单点登陆的完整demo,java实现,支持https,包含cas服务器和2个客户端代码,解压即用,运行之前请阅读注意说明,记得添加证书至jdk信任,如果实在无法运行可以参考我的博客相关文章