CAS4.0 4.1 服务器端搭建(一)

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.casgroupId>
    <artifactId>cas-server-support-jdbcartifactId>
    <version>4.1.6version>
dependency>

1.2 数据库连接池,4.2自带了c3p0的连接池,根据情况使用。

<dependency>
     <groupId>com.alibabagroupId>
     <artifactId>druidartifactId>
     <version>1.0.18version>
dependency>
<dependency>
     <groupId>mysqlgroupId>
     <artifactId>mysql-connector-javaartifactId>
     <version>5.1.38version>
dependency>

1.3 在cas.properties中写入数据库连接配置。

在applicationContext.xml 添加一个数据源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"/>
    

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的支持,可以自己去拷一个或者重写一个。

    "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,添加两个属性。

id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
        p:defaultLocale="zh-CN" p:cookieName="locale" p:cookieDomain=".yourdomain.com" />

3.返回更多的用户信息

deployerConfigContext.xml中找到attributeRepositoryattrRepoBackingMap,修改为:

  <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.jsonattributeReleasePolicy@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

 ${fn:escapeXml(principal.id)}
 <%-- 添加这段 -- start -->
 if 
 test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes) > 0}">
            
                forEach var="attr"         items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">
                    ${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}${fn:escapeXml(attr.key)}>
                forEach>
            
        if>
        if test="${not empty pgtIou}">
            ${pgtIou}
        if>
<%-- 添加这段 -- end-->
if test="${fn:length(chainedAuthentications) > 0}">
      
      forEach var="proxy" items="${chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(chainedAuthentications)}" step="1">
           ${fn:escapeXml(proxy.principal.id)}
       forEach>
       
if>

<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>

ticketGrantingTicketCookieGenerator.xmlticketGrantingTicketCookieGenerator bean
添加属性:






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日志数据库持久化

你可能感兴趣的:(CAS,服务器,CAS4-x,开源项目)