Build Your Own Cas Service - Pro

示例代码: https://github.com/superalsrk/modify-jasig-cas ,以下所有描述都基于版本 3.5.2.1

Generally Design

我们可以把一个war项目作为dependency,然后创建一个web项目webapp,然后只要将创建项目的 web.xml 和 index.jsp 去掉, 整个项目就能跑了。

更重要的是,如果要对war进行扩展, 只要讲war对应的文件拷贝一份到webapp,打包的时候便能自动到替换。下面讲的 修改XXX文件, 都是对其拷贝进行修改,特此声明:

webapp module的pom为pom.xml

Auth Module

自定义Credentials

Credentials是一个用户凭证, 可以理解为一个简易的pojo, 只要实现Credentials接口即可,我们的自定义凭证中除了用户名密码,还加了一个字段 product : String, 表明要登录的产品类型

在Web Module中,需要进行如下修改

1 . 在登录表单增加product字段,具体操作详见下个Section
2 . 在 /WEB-INF/login-webflow.xml 中,修改credentials类型为自定义的Credentials

<var name="credentials" class="com.nbrc.sso.cas.principal.NbrcCredentials"/>

3 . 然后继续在 login-webflow.xml里找到 viewLoginForm ,进行数据绑定

<view-state id="viewLoginForm" view="casLoginView" model="credentials">  
       <binder>  
           <binding property="username" />  
           <binding property="password" />  
           <binding property="product"/> <!--增加这一行 -->  
       </binder>  
       ...  
</view-state>  

自定义Handler

自定义Handler只要实现接口 AuthenticationHandler 即可

1 . 如果要在前台显示一个 权限不足 的信息, 只需在Handler里throw一个自定义的 AuthenticationException 即可
2 . support 接口用来声明handler是否支持某种类型的凭证
3 . 修改 /WEB-INF/deployConfigContext.xml ,进行handler的配置

<property name="authenticationHandlers">
            <list>
                <bean
                    class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
                    p:httpClient-ref="httpClient" p:requireSecure="false" />

                <bean
                    class="com.miaozhen.dashboard.darkportal.mechanism.DarkportalAuthenticationHandler" />
            </list>
</property>

自定义Resolver

Resolver是一个Credentials 到 Principal的转换器, 其中Principal其实是javaEE中就已经定义好的

1 . 修改 /WEB-INF/deployConfigContext.xml ,进行Resolver的配置

<property name="credentialsToPrincipalResolvers">
            <list>
                <bean
                    class="com.miaozhen.dashboard.darkportal.mechanism.DarkportalCredentialsToPrincipalResolver">

                </bean>

                <bean
                    class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
            </list>
</property>

2 . resolver可以返回一个Principal, 个人觉得比较好用的方式是返回一个 #SimplePrincipal# ,除了用户的user信息外,还可以返回一个 AttrMap,不过需要参考下章进行Resolver视图的修改

Map<String, Object> map = new HashMap<String, Object>();
map.put(ATTR_USERNAME, mzCredentials.getUsername());
map.put(ATTR_PASSWORD, mzCredentials.getPassword());

SimplePrincipal simple = new SimplePrincipal(mzCredentials.getUsername(), map);

Web Module

自定义登陆页面

正常的做法应该是copy一份defaults文件夹,然后在resources里copy对应的主题配置文件,最后在cas.properties里配置一下主题,不过为了省事直接改defaults里的文件就可以了

default/ui/casLoginView.jsp 就是默认的登录界面,可以给form表单增加多余的字段。需要注意的是:form表单里还有一堆cas自带的input,这个在改页面的时候不能删掉。

自定义返回用户信息

1 . 在resolver中虽然返回了更多Attr,不过默认的Resolver视图不支持返回更多属性,需要对 protocol/2.0/casServiceValidationSuccess.jsp 页面进行扩展.

<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationSuccess>
        <cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user>
        <c:if
            test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes) > 0}">
            <cas:attributes>
                  <c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">
                    <cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>
                </c:forEach>
            </cas:attributes>
        </c:if>
        <c:if test="${not empty pgtIou}">
            <cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>
        </c:if>
        <c:if test="${fn:length(assertion.chainedAuthentications) > 1}">
            <cas:proxies>
                <c:forEach var="proxy" items="${assertion.chainedAuthentications}"
                    varStatus="loopStatus" begin="0"
                    end="${fn:length(assertion.chainedAuthentications)-2}" step="1">
                    <cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy>
                </c:forEach>
            </cas:proxies>
        </c:if>
    </cas:authenticationSuccess>
</cas:serviceResponse>

2 . 在client端,使用如下代码就可以获取多余属性

AttributePrincipal attribute = (AttributePrincipal) request.getUserPrincipal();
AttributePrincipal.getName()  就是 Resolver中返回的SimplePrincipal名字
AttributePrincipal.getAttributes() 就是Resolver中返回的SinmplePrincipal的attributes

3 . 注意把deployerConfigContext.xml中 serviceRegistryDao全部删掉(cas),参考资料


CAS退出功能

默认的JASIG退出成功后会跳到一个 推出成功页面, 但我们想要的效果是退出CAS,并且退出已经登录的应用, 那么可以进行如下的配置:

  1. 如果只是退出应用,那么在此访问页面的时候,cas-client又会向cas-server端进行请求验证,然后自动登录,所以同时退出cas和应用即可
  2. 修改 cas-servlet.xml , 在 logoutController 的bean中增加属性 p:followServiceRedirects="true"
  3. 假如应用已经有一个退出controller,此contoller用来清空session,那么链接 http://cas.example.org/logout?service=http://localhost:8080/logout 便可以正常退出

THE END

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容