cas实现sso

来源:互联网 发布:淘宝积分就是淘气值吗 编辑:程序博客网 时间:2024/05/08 11:37

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客户端,服务端认证完成
0 0