CAS4.0 4.1 服务器端搭建(一)
2016-04-14 09:37
211 查看
CAS(Central Authentication Service) 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。
从结构上看,CAS 包含两个部分: CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。
因为4.2现在还不是很稳定,配置4.0的时候,我修改了一部分源码,所以就以4.1.6为例子记录一下CAS Server的配置过程。4.1与4.0的区别是4.1支持用户salt,tgc(TGT cookie加密),log4j2,saml。4.2之前使用的是maven build,bean使用xml配置,而4.2使用的是gradle,大部分配置使用spring自动注入。配置的时候最好是去官网下载源码包,导入后配置。
1.使用JDBC数据库做用户验证
1.1 在cas-server-webapp的pom.xml里面加入jdbc的支持。
<dependency> <groupId>org.jasig.cas</groupId> <artifactId>cas-server-support-jdbc</artifactId> <version>4.1.6</version> </dependency>
1.2 数据库连接池,4.2自带了c3p0的连接池,根据情况使用。
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.18</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency>
1.3 在cas.properties中写入数据库连接配置。
在applicationContext.xml 添加一个数据源bean<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="${cas.database.driverClass}"/> <property name="url" value="${cas.database.url}"/> <property name="username" value="${cas.database.user}"/> <property name="password" value="${cas.database.password}"/> <property name="minIdle" value="${cas.database.pool.minSize}"/> <property name="maxActive" value="${cas.database.pool.maxSize}"/> <property name="validationQuery" value="${cas.database.pool.connectionHealthQuery}"/> <property name="testWhileIdle" value="true"/> <property name="timeBetweenEvictionRunsMillis" value="1800"/> <property name="filters" value="stat, wall"/> <property name="testOnBorrow" value="false"/> <property name="testOnReturn" value="false"/> <!-- poolPreparedStatements只支持oracle和mysql5.5+ --> <property name="poolPreparedStatements" value="true"/> <property name="maxOpenPreparedStatements" value="150"/> </bean>
1.4 在 cas.properties中添加jdbc认证查询的sql,因为cas使用的是spring-jdbc,所以语法是spring-jdbc的语法。
# 查询sql,不配置可以根据后面的参数拼接,建议配置上 cas.jdbc.authn.query.encode.sql= select password, salt from user where username=? # 对数据库取出的密码比对时,对用户输入密码的加密算法,不是passwordEncoder。 cas.jdbc.authn.query.encode.alg= MD5 # 配置静态的全局salt,默认为空 # cas.jdbc.authn.query.encode.salt.static= # 数据库密码字段,默认password # cas.jdbc.authn.query.encode.password= # 数据库salt字段,默认salt # cas.jdbc.authn.query.encode.salt= # 数据库存储加密算法加密次数的字段,默认numIterations # cas.jdbc.authn.query.encode.iterations.field= # 配置方式的加密次数,默认0(加密一次),实际加密次数=num+1 # cas.jdbc.authn.query.encode.iterations=
配置jdbc认证处理器,在
deployerConfigContext.xml中查询bean
primaryAuthenticationHandler,将class替换成
org.jasig.cas.adaptors.jdbc.QueryAndEncodeDatabaseAuthenticationHandler,这个类是4.1加入的,所以如果你是使用的4.0,又想要salt的支持,可以自己去拷一个或者重写一个。
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryAndEncodeDatabaseAuthenticationHandler" c:datasource-ref="dataSource" c:sql="${cas.jdbc.authn.query.encode.sql:}" c:algorithmName="${cas.jdbc.authn.query.encode.alg:}" p:passwordEncoder-ref="passwordEncoder"/>
c:datasource-ref是认证的数据源,c:sql为查询的sql,c:algorithmName用户输入密码加密算法,p:passwordEncoder-ref,对用户输入密码预加密,默认是PlainTextPasswordEncoder,不加密。这个加密在c:algorithmName之前,且不带salt,c:algorithmName是带salt的加密。如果要自己实现passwordEncoder,实现PasswordEncoder接口就可以了。这里就不给出具体实现了。实现以后,记得配置一个passwordEncoder bean,引用你的实现,才能生效。
在数据库中添加一个按你的加密算法生成的用户名,就可以了发布,测试了。
2.CAS的i18n是使用的spring的i18n,如果要自定义cookie的名称,域,在cas-servlet.xml中,找到CookieLocaleResolver,添加两个属性。
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" p:defaultLocale="zh-CN" p:cookieName="locale" p:cookieDomain=".yourdomain.com" />
3.返回更多的用户信息
deployerConfigContext.xml中找到
attributeRepository和
attrRepoBackingMap,修改为:
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao" c:ds-ref="dataSource" c:sql="select * from user where username=?" p:resultAttributeMapping-ref="attrRepoBackingMap"/> <util:map id="attrRepoBackingMap" > <entry value="id" key="id" /> <entry value="username" key="username" /> <entry value="phone" key="phone" /> <entry value="nickname" key="nickname" /> <entry value="pic" key="pic" /> <entry value="birthDate" key="birth_date" /> <entry value="sex" key="sex" /> </util:map>
HTTPSandIMAPS-10000001.json将
attributeReleasePolicy@class修改为返回
attrRepoBackingMap定义的所有属性
org.jasig.cas.services.ReturnAllAttributeReleasePolicy
如果要指定
attrRepoBackingMap的部分属性,则使用下面的配置
"attributeReleasePolicy" : { "@class" : "org.jasig.cas.services.ReturnAllowedAttributeReleasePolicy", "allowedAttributes" : [ "java.util.ArrayList", [ "cn", "mail", "sn" ] ] }
客户端从
request.getUserPrincipal()获取用户信息
修改
\WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp
<cas:user>${fn:escapeXml(principal.id)}</cas:user> <%-- 添加这段 -- start --> <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> <%-- 添加这段 -- end--> <c:if test="${fn:length(chainedAuthentications) > 0}"> <cas:proxies> <c:forEach var="proxy" items="${chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(chainedAuthentications)}" step="1"> <cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy> </c:forEach> </cas:proxies> </c:if>
<!DOCTYPE html"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>返回值测试</title> </head> <body> <% request.setCharacterEncoding("UTF-8"); AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal(); Map attributes = principal.getAttributes(); String userid=(String)attributes.get("id"); String username = (String)attributes.get("username"); String nickname = (String)attributes.get("nickname"); String pic=(String)attributes.get("pic"); %> <div>飞奔的蜗牛博客:返回值演示</div> <ul> <li>userid:<%= userid%></li> <li>username:<%= username%></li> <li>nickname:<%= nickname%></li> <li>pic:<%= pic%></li> </ul> </body> </html>
4. 配置secure cookie
ticketGrantingTicketCookieGenerator.xml中
ticketGrantingTicketCookieGeneratorbean
添加属性:
<!-- p:cookieSecure 默认false --> <!-- p:cookieHttpOnly 默认false,设置为true后,ajax无法方法TGT cookie --> <!-- p:cookieMaxAge 有效期,默认-1 --> <!-- p:cookiePath cookie路径,默认/cas/ --> <!-- p:cookieDomain 默认为当前域名,我们需要改成 .yourdomain.com --> bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator" p:cookieSecure="${cas.cookie.cookieSecure:true}" p:cookieHttpOnly="${cas.cookie.cookieHttpOnly:true}" p:cookieMaxAge="${cas.cookie.cookieMaxAge:-1}" p:cookieName="${cas.cookie.cookieName:CASTGC}" p:cookiePath="${cas.cookie.path:/}" p:cookieDomain="${cas.cookie.cookieDomain:}" />
5. 配置cas登录的地址
cas.properties:server.name=youdomain.com
CAS的数据库认证方式就完成了,打包成war包发布。下一次记录cas的audit日志数据库持久化
相关文章推荐
- Jquery实现可拖拽的树菜单
- layoutSubviews
- Spring框架整合Struts2使用Validation框架验证表单用户输入数据的详细教程
- AsyncTask(异步线程)详解
- JProfiler监控本地服务程序性能
- python 小模块--platform
- 63. Unique Paths II【M】【30】
- Web API接口之FileReader
- linux第四章笔记
- 搜索旋转排序数组 II
- iOS instruments 介绍
- bzoj 4454: C Language Practice O(n)-O(1) gcd
- K-means聚类
- Thread中的实例方法
- 基于Java NIO的Socket通信
- vim编辑器
- 本地项目的jsp跳转到另外一个网站或项目的jsp
- Modbus协议的CRC校验码是高位在前还是低位在前的问题
- 一个电脑双显示屏,用于画板子(有待更新)
- oracle判断一个字符串中是否包含另外一个字符串(想要不论顺序或者不相邻的字符)