用CAS在tomcat6实现SSO

一、软件版本

    Tomcat6.018,

    CAS-SERVER 3.3.1, CAS-CLIENT-JAVA 2.1.1

 

二、准备工作

   1、在Tomcat配置SSL

在/$CATA_HOME$/conf/server.xml中加入下面的配置,记住端口号为8443,口令为changeit。

<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"  
           port="8443" minSpareThreads="5" maxSpareThreads="75"  
           enableLookups="true" disableUploadTimeout="true"    
           acceptCount="100"  maxThreads="200"  
           scheme="https" secure="true" SSLEnabled="true"  
           clientAuth="false" sslProtocol="TLS"  
           keystoreFile="server.keystore"    
           keystorePass="changeit" />

  2、生成证书

将以下命令作为一个bat文件,双击运行它(假设CAS部署在http://1GNW92X.com.cn):

rem 生成证书,用户名输入locahost
keytool -delete -alias tomcat -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit
keytool -delete -alias tomcat -storepass changeit

keytool -genkey -alias tomcat -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore -validity 360

rem 将证书导入的JDK的证书信任库
keytool -export -trustcacerts -alias tomcat -dname "1GNW92X.com.cn" -file server.cer -keystore  server.keystore -storepass changeit
keytool -import -trustcacerts -alias tomcat -file server.cer -keystore  "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit

   3、如果业务平台WebApp在CAS以外的机器上,再在业务机运行下面的指令:

java InstallCert 1GNW92X.com.cn:8443

 

三、配置CAS-SERVER应用

将 cas-server3.3.1.zip包里面的case-server-3.3.1.war改名cas.war放倒tomcat的webApps目录,修改/WEB-INF/deployerConfigContext.xml文件,主要替换以下几个部分:

1、<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

==>>

   <bean id="QueryDatabaseAuthenticationHandler"
          class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
        <property name="dataSource" ref="casDataSource" />
        <property name="sql" value="SELECT c_userpwd FROM T_USER WHERE c_userid=?" />
        <!--property name="passwordEncoder" ref="myPasswordEncoder"/-->
    </bean>

   <bean id="casDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
       <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
       <property name="jdbcUrl" value="jdbc:oracle:thin:@172.21.6.212:1521:ORCL" />
       <property name="user" value="longtop" />
       <property name="password" value="longtop" />
       <property name="autoCommitOnClose" value="true"/>
       <property name="checkoutTimeout" value="5000"/>
       <property name="initialPoolSize" value="10"/>
       <property name="minPoolSize" value="10"/>
       <property name="maxPoolSize" value="30"/>
       <property name="maxIdleTime" value="100000"/>
       <property name="acquireIncrement" value="5"/>
    </bean>

2、<bean id="attributeRepository"  class="org.jasig.services.persondir.support.StubPersonAttributeDao">
         <property name="backingMap">
             <map>
                 <entry key="uid" value="uid" />
                 <entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
                 <entry key="groupMembership" value="groupMembership" />
             </map>
         </property>
    </bean>

==>>

<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
        <constructor-arg index="0" ref="casDataSource"/>
        <constructor-arg index="1">
            <list>
                <value>username</value>
            </list>
        </constructor-arg>
        <constructor-arg index="2" value="select c_userid,c_username,c_defaultgrp from T_USER where c_userid=?"/>
        <property name="columnsToAttributes">
            <map>
                <entry key="c_userid" value="userId"/>
                <entry key="c_username" value="fullName"/>
                <entry key="c_defaultgrp" value="groupId"/>
            </map>
        </property>
    </bean>

 

四、搞定客户端webApp

1、配置web.xml

  <listener>
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
  </listener>
  <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>/*</url-pattern>
  </filter-mapping>
  <filter>
    <filter-name>CAS Filter</filter-name>
    <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
      <param-value>https://1GNW92X.com.cn:8443/cas/login</param-value>
    </init-param>
    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
      <param-value>https://1GNW92X.com.cn:8443/cas/serviceValidate</param-value>
    </init-param>
    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
      <param-value>localhost:8080</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CAS Filter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

2、修改edu.yale.its.tp.cas.client.ServiceTicketValidator中解析报文的方法(原来是用sax),改为用jdom

    private static String TAG_AUTHEN_SUCCESS = "authenticationSuccess";
    private static String TAG_AUTHEN_FAILURE = "authenticationFailure";
    private static String TAG_AUTHEN_USER = "user";
    private static String TAG_AUTHEN_ATTRIBUTES = "attributes";
    private static String TAG_AUTHEN_PGT = "proxyGrantingTicket";
    private static String TAG_AUTHEN_PROXIES = "proxies";
    private static String TAG_AUTHEN_ATTRIBUTE = "attribute";
    private static String TAG_AUTHEN_ATTRNAME = "name";
    private static String TAG_AUTHEN_ATTRVALUE = "value";
    private static String TAG_AUTHEN_PROXY = "proxy";
    private static String TAG_AUTHEN_ERRORCODE = "code";
    @SuppressWarnings("unchecked")
    private void parseResponse(String xmlContent)throws IOException, SAXException{
        receipt = new CASReceipt();
        receipt.setCasValidateUrl(casValidateUrl);
        receipt.setProxyCallbackUrl(proxyCallbackUrl);
       
        ByteArrayInputStream bin = new ByteArrayInputStream(xmlContent.getBytes());
        SAXBuilder builder = new SAXBuilder();
        builder.setValidation(false);
        Document doc = null;
        try {
            doc = builder.build(bin);
        } catch (JDOMException e) {
            throw new SAXException(e);
        }
       
        Element root = doc.getRootElement().getChild(TAG_AUTHEN_SUCCESS);
        if (root != null){
            List<Element> lstNode = root.getChildren();
            List<Element> userAttrs;
            List<Element> proxyList;
            for (Element node : lstNode){
                if (node.getName().equals(TAG_AUTHEN_USER)){
                    receipt.setUserName(node.getTextTrim());
                }else if (node.getName().equals(TAG_AUTHEN_ATTRIBUTES)){
                    userAttrs = node.getChildren(TAG_AUTHEN_ATTRIBUTE);
                    for (Element attr : userAttrs){
                        receipt.putUserAttribute(
                                    attr.getChildTextTrim(TAG_AUTHEN_ATTRNAME),
                                    attr.getChildTextTrim(TAG_AUTHEN_ATTRVALUE) );
                    }
                }else if (node.getName().equals(TAG_AUTHEN_PGT)){
                    receipt.setPgtIou(node.getTextTrim());
                }else if (node.getName().equals(TAG_AUTHEN_PROXIES)){
                    proxyList = node.getChildren(TAG_AUTHEN_PROXY);
                    for (Element proxy : proxyList){
                        this.proxyList.add( proxy.getTextTrim() );
                    }
                }
            }
        }else{
            root = doc.getRootElement().getChild(TAG_AUTHEN_FAILURE);
            errorCode = root.getAttributeValue(TAG_AUTHEN_ERRORCODE);
            errorMessage = root.getTextTrim();
        }
    }

 

修改validate()

    private CASReceipt receipt;
    protected List proxyList;

    public void validate() throws IOException, SAXException,
              ParserConfigurationException {

        //前面的部分不修改

        String response = SecureURL.retrieve(sb.toString());        
        response = response.replaceAll("<cas:", "<").replaceAll("</cas:", "</");
        this.parseResponse(response);
        if (!receipt.validate()) {
            throw new ParserConfigurationException(
                    "Validation of [" + this
                            + "] did not result in an internally consistent CASReceipt.");
        }

   }

   public CASReceipt getReceipt(){
        return this.receipt;
   }

3、修改CASFilter

     private ILoginClientService loginClient;  //自定义的接口,用于实现客户端的Session

 

     private CASReceipt getAuthenticatedUser(HttpServletRequest request)
                throws ServletException, CASAuthenticationException {
        //前面的部分不修改
        //return CASReceipt.getReceipt(ServiceTicketValidator);
        try {
            ticketValidator.validate();
            return ticketValidator.getReceipt();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

 

    public void doFilter(ServletRequest req, ServletResponse resp,
                     FilterChain chain)throws ServletException, IOException {

        //前面的部分不修改

        if (loginClient != null){
            System.out.println("application do login and set session....");
            loginClient.login(request, response, receipt.getUserName());
        }
        chain.doFilter(request, response);

   }

   public void init(FilterConfig config) throws ServletException {

        //前面的部分不修改

        if (loginClient != null){
            System.out.println("application do login and set session....");
            loginClient.login(request, response, receipt.getUserName());
        }
        chain.doFilter(request, response);

   }

4、新增类

public interface ILoginClientService{
    public static String REFER_ID = "com.longtop.dev6sso.LoginService";
   
    public void login(HttpServletRequest request, HttpServletResponse response,
                        String loginName);
   
    public void logout(HttpServletRequest request, HttpServletResponse response,
                        String loginName);

}

5、别忘了在客户端Spring配置

    <bean id="com.longtop.dev6sso.LoginService"
          class="com.longtop.demo.sso.DemoLoginService">
    </bean>

 

==================================================

End.


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值