cas实现sso

sso: 分为server client
server即服务端,一个,功能:系统下各个应用的认证都在这里进行
client即客户端,应用,n个。

对于我们这个系统来说
客户端为 zjcms
服务端为 cas_server
我们用2个tomcat分别跑这两个应用,登录cms时,跳转到cas_server登录,服务端认证,认证通过,返回到客户端,并携带我们所需要的信息.

配置客户端:我们使用cas-client 版本为3.2.1
配置服务端:我们使用cas-server 版本为4.0.0

对于客户端配置:
在web.xml中

<!--cas client -->
<listener>
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>

<!--这个filter作用于注销登录 -->
<filter>
    <filter-name>CAS Single Sign Out Filter</filter-name>
    <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CAS Single Sign Out Filter</filter-name>
    <url-pattern>/admin/*</url-pattern>
</filter-mapping>


<!-- 登录认证,未登录用户导向CAS Server进行认证 -->
<filter>
    <filter-name>CAS Filter</filter-name>
    <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
    <init-param>
        <param-name>casServerLoginUrl</param-name>
        <param-value>http://localhost:9080/login</param-value>
    </init-param>
    <init-param>
        <param-name>serverName</param-name>
        <param-value>http://localhost:8080</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CAS Filter</filter-name>
    <url-pattern>/admin/*</url-pattern>
    <url-pattern>/ShowReport.wx</url-pattern>
</filter-mapping>


<filter>
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 存放Assertion到ThreadLocal中   -->
<filter>
    <filter-name>CAS Assertion Thread Local Filter</filter-name>
    <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CAS Assertion Thread Local Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>CAS Validation Filter</filter-name>
    <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
    <init-param>
        <param-name>casServerUrlPrefix</param-name>
        <param-value>http://localhost:9080</param-value>
    </init-param>
    <init-param>
        <param-name>serverName</param-name>
        <param-value>http://localhost:8080</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CAS Validation Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

对于客户端来说:cas 认证成功默认是返回userName,存储在request的principal中,
认证成功还会返回一个ticket存储在session中,我们注销登录就是通过清除session中的令牌实现.
我们通过
AttributePrincipal principal = (AttributePrincipal) getRequest().getUserPrincipal();
获取返回的信息(后面会讲到如何设置我们需要返回的信息)

对于服务端的配置:主要是在WEB-INF 下的deployerConfigContext.xml中

cas默认的一个bean配置为




<bean id="primaryAuthenticationHandler"
          class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
        <property name="users">
            <map>
                <entry key="admin" value="admin"/>
            </map>
        </property>
    </bean>
这是未配置数据源

项目中,实现我们自己的数据源,则需要如下配置
 <bean id="primaryAuthenticationHandler"   class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
        <property name="dataSource" ref="dataSource"></property>
        <property name="sql" value="select PASSWORD from T_USER where NAME=?"></property>
        <property name="passwordEncoder" ref="BASE64Encoder"></property>
    </bean>
    在这个bean中2个功能:一个配置数据源,增加一个bean
       <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"><value>${jdbc.Driver}</value></property>
        <property name="url"><value>${jdbc.url}</value></property>
        <property name="username"><value>${jdbc.name}</value></property>
        <property name="password"><value>${jdbc.pwd}</value></property>
    </bean>



    另一个是配置我们自己的加密法则,
    我们cms使用的是自定义的base64加密
    添加一个bean

        <bean id="BASE64Encoder" class="cn.zfgc.passwordEncoder.DefaultEncoder">
        <constructor-arg index="0">
            <value>BASE64</value>
        </constructor-arg>
    </bean>


     在java中新建一个DefaultEncoder  实现PasswordEncoder接口
     这种加密不算很好,要严谨一点我们需要使用加盐算法

   public class DefaultEncoder implements PasswordEncoder {
    public DefaultEncoder(String s) {
    }
    @Override
    public String encode(String password) {
        return base64Encode(password);
    }
    /**
     * 加密
     */
    private  String base64Encode(String str){
        byte[] b = null;
        String result = null;
        try {
            b = str.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (b != null) {
            result = new BASE64Encoder().encode(b);
        }
        return result;
    }
}


这样基本的配置已经完成,但是cas默认是要使用https.所以我们需要将https设置为http
第一步:
webapps\cas\WEB-INF\spring-configuration\warnCookieGenerator.xml   
<bean id="warnCookieGenerator   这个bean中  将p:cookieSecure="true" 为 p:cookieSecure="false"

第二步:
webapps\cas\WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml 
中<bean id="ticketGrantingTicketCookieGenerator"   将 p:cookieSecure="true" 为 p:cookieSecure="false"

第三步:
webapps\cas\WEB-INF\deployerConfigContext.xml中
<bean id="proxyAuthenticationHandler"     末尾增加 p:requireSecure="false"

第四步:
webapps\cas\WEB-INF\deployerConfigContext.xml中
找到<bean class="org.jasig.cas.services.RegexRegisteredService">这个bean

默认配置为:
<bean class="org.jasig.cas.services.RegexRegisteredService"-->
              <!--p:id="0" p:name="HTTP and IMAP" p:description="Allows HTTP(S) and IMAP(S) protocols"-->
              <!--p:serviceId="^(https?|imaps?)://.*" p:evaluationOrder="10000001" />
                </bean>


更改为           
<bean class="org.jasig.cas.services.RegexRegisteredService">
        <property name="id" value="1" />
        <property name="name" value="HTTP and IMAP on example.com" />
        <property name="description" value="Allows HTTP(S) and IMAP(S) protocols" />
        <property name="serviceId" value="^(http?|imaps?)://.*" />
        <property name="evaluationOrder" value="10000001" />
        <property name="allowedAttributes">
            <list>
                <value>NAME</value>
                <value>ROLE_ID</value>
            </list>
        </property>
          </bean>


这样就ok了

配置服务端自定义返回数据:
第一步:
默认配置为


    <bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"
            p:backingMap-ref="attrRepoBackingMap" >
    </bean>

    <util:map id="attrRepoBackingMap">
        <entry key="uid" value="uid" />
        <entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> 
        <entry key="groupMembership" value="groupMembership" />
    </util:map>  
修改为
    <bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
     <constructor-arg index="0" ref="dataSource"></constructor-arg>
        <constructor-arg index="1" value="select * from T_USER where {0}"></constructor-arg>
        <property name="queryAttributeMapping">
            <map>
                <entry key="username" value="NAME"></entry>
            </map>
        </property>
        <property name="resultAttributeMapping">
            <map>
             <entry key="NAME" value="NAME"/>
                <entry key="ROLE_ID" value="ROLE_ID"/>
            </map>
        </property>
    </bean>

在我们项目中 需要返回一个ROLE_ID,那么
我们在resultAttributeMapping中多配置一个  
 <entry key="ROLE_ID" value="ROLE_ID"/>   value对应数据库字段

 第二步:
 找到 id="registeredServicesList"  修改allowedAttributes为
  <property name="allowedAttributes">
            <list>
                <value>NAME</value>
                <value>ROLE_ID</value>
            </list>
        </property>

 cas客户端,服务端认证完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值