`

CAS3.0 定制验证(转)

    博客分类:
  • cas
cas 
阅读更多

  • 前言:
     CAS v2 定制自己的验证逻辑,大家已经很清楚了.[官方提供的sample只简单校验username,password是否相等].开发者可以通过实现PasswordHandler接口来使用其它的认证方式,如数据库用户的用户名和密码匹配认证,数字签名的验证,操作系统用户认证,以及LDAP用户认证等模式。比如:
 <context-param>
        <param-name>edu.yale.its.tp.cas.authHandler</param-name>
        <param-value>
             edu.yale.its.tp.cas.auth.provider.KerberosAuthHandler
        </param-value>
  </context-param>
 
  • 改变:
    Yale CAS3代码全部重构,功能增强,且使用了Spring和SpringWebFlow[相关知识参见Spring论坛].
  • 涉及点分析:
      deployerConfigContext.xml是描述部署细节的,他通过web.xml如下描述而加载
 <context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>
    /WEB-INF/applicationContext.xml,
    /WEB-INF/mydeployerConfigContext.xml
   </param-value>
</context-param>
 
        contextConfigLocation属性名在Spring MVC体系中,会自动获取.
----------------------------
deployerConfigContext.xml文件是所有CAS deployer应该关心的东西,在这里,你可以对CAS的三个核心玩意进行自己的定制:
1.AuthenticationManager
<!--
   | This bean declares our AuthenticationManager. The CentralAuthenticationService service bean
   | declared in applicationContext.xml picks up this AuthenticationManager by reference to its id, 
   | "authenticationManager". Most deployers will be able to use the default AuthenticationManager
   | implementation and so do not need to change the class of this bean. We include the whole
   | AuthenticationManager here in the userConfigContext.xml so that you can see the things you will
   | need to change in context.
   +-->

2.credentialsToPrincipalResolvers
<!--
      | UsernamePasswordCredentialsToPrincipalResolver supports the UsernamePasswordCredentials that we use for /login 
      | by default and produces SimplePrincipal instances conveying the username from the credentials.
      | 
      | If you've changed your LoginFormAction to use credentials other than UsernamePasswordCredentials then you will also
      | need to change this bean declaration (or add additional declarations) to declare a CredentialsToPrincipalResolver that supports the
      | Credentials you are using.
      +-->
3.authenticationHandlers
这个authenticationHandler可是所有CAS用户都需要修改的地方

<!--
      | This is the authentication handler declaration that every CAS deployer will need to change before deploying CAS 
      | into production. The default SimpleTestUsernamePasswordAuthenticationHandler authenticates UsernamePasswordCredentials
      | where the username equals the password. You will need to replace this with an AuthenticationHandler that implements your
      | local authentication strategy. You might accomplish this by coding a new such handler and declaring
      | edu.someschool.its.cas.MySpecialHandler here, or you might use one of the handlers provided in the adaptors modules.
      +-->

  • 实现:
     思路:没撒子说的,就是实现自己的Hadnle.为了避免重新编译cas代码,使用ant部署自己的jar到目标的lib中,并替换web.xml以及引进自己的配置文件mydeployerConfigContext.xml
     步骤:
      A:在应用服务器中配置DS[略]
       B:修改web.xml
 <context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>
    /WEB-INF/applicationContext.xml,
   /WEB-INF/mydeployerConfigContext.xml
   </param-value>
</context-param>
 
      C:web.xml加入DS引用
        <resource-ref>
<description>
    Resource reference to a factory for java.sql.Connection
    instances that may be used for talking to a particular
    database that is configured in the server.xml file.
</description>
<res-ref-name>
    jdbc/EmployeeDB
</res-ref-name>
<res-type>
    javax.sql.DataSource
</res-type>
<res-auth>
    Container
</res-auth>
</resource-ref>
 
D:添加mydeployerConfigContext.xml
内容如下:
   <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--
   | This bean declares our AuthenticationManager. The CentralAuthenticationService service bean
   | declared in applicationContext.xml picks up this AuthenticationManager by reference to its id, 
   | "authenticationManager". Most deployers will be able to use the default AuthenticationManager
   | implementation and so do not need to change the class of this bean. We include the whole
   | AuthenticationManager here in the userConfigContext.xml so that you can see the things you will
   | need to change in context.
   +-->
<bean id="authenticationManager"
   class="org.jasig.cas.authentication.AuthenticationManagerImpl">
   <!--
    | This is the List of CredentialToPrincipalResolvers that identify what Principal is trying to authenticate.
    | The AuthenticationManagerImpl considers them in order, finding a CredentialToPrincipalResolver which 
    | supports the presented credentials.
    |
    | AuthenticationManagerImpl uses these resolvers for two purposes. First, it uses them to identify the Principal
    | attempting to authenticate to CAS /login . In the default configuration, it is the DefaultCredentialsToPrincipalResolver
    | that fills this role. If you are using some other kind of credentials than UsernamePasswordCredentials, you will need to replace
    | DefaultCredentialsToPrincipalResolver with a CredentialsToPrincipalResolver that supports the credentials you are
    | using.
    |
    | Second, AuthenticationManagerImpl uses these resolvers to identify a service requesting a proxy granting ticket. 
    | In the default configuration, it is the HttpBasedServiceCredentialsToPrincipalResolver that serves this purpose. 
    | You will need to change this list if you are identifying services by something more or other than their callback URL.
    +-->
   <property name="credentialsToPrincipalResolvers">
    <list>
     <!--
      | UsernamePasswordCredentialsToPrincipalResolver supports the UsernamePasswordCredentials that we use for /login 
      | by default and produces SimplePrincipal instances conveying the username from the credentials.
      | 
      | If you've changed your LoginFormAction to use credentials other than UsernamePasswordCredentials then you will also
      | need to change this bean declaration (or add additional declarations) to declare a CredentialsToPrincipalResolver that supports the
      | Credentials you are using.
      +-->
     <bean
      class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />
     <!--
      | HttpBasedServiceCredentialsToPrincipalResolver supports HttpBasedCredentials. It supports the CAS 2.0 approach of
      | authenticating services by SSL callback, extracting the callback URL from the Credentials and representing it as a
      | SimpleService identified by that callback URL.
      |
      | If you are representing services by something more or other than an HTTPS URL whereat they are able to
      | receive a proxy callback, you will need to change this bean declaration (or add additional declarations).
      +-->
     <bean
      class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
    </list>
   </property>
   <!--
    | Whereas CredentialsToPrincipalResolvers identify who it is some Credentials might authenticate, 
    | AuthenticationHandlers actually authenticate credentials. Here we declare the AuthenticationHandlers that
    | authenticate the Principals that the CredentialsToPrincipalResolvers identified. CAS will try these handlers in turn
    | until it finds one that both supports the Credentials presented and succeeds in authenticating.
    +-->
   <property name="authenticationHandlers">
    <list>
     <!--
      | This is the authentication handler that authenticates services by means of callback via SSL, thereby validating
      | a server side SSL certificate.
      +-->
     <bean
      class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" />  
     <bean
      class="cn.com.tiansky.cas.authenticationHandlers.DsHandlers" />
    </list>
   </property>
</bean>
</beans>
 
E:编写DsHandlers
package cn.com.tiansky.cas.authenticationHandlers;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import cn.com.tiansky.tool.MD5;

/**
* 支援CAS3,。实现自己的Handler(未自定义credentials,如因业务需要而修改,则需要同时
* 修改LoginFormAction和定义自己的credentialsToPrincipalResolvers)\
* ,你的需求也许包括了需要通过检索数据库来比配credential中的username和password,
* 也可能不是数据库,而是LDAP什么的,总之你得开始制作自己的handler了!
* credential的种类是很多的,有的基于用户名和密码,有的基于http请求,
* 如果你有你自己的credential的话,就得为它制作有一个handler,
* 来告诉CAS如何处理这种特有的credential。
* @author tiansky
* @version 1.0
*
*/
public final class DsHandlers extends
AbstractUsernamePasswordAuthenticationHandler{
/**
* Logger log:log4j日志
*/
private Logger log=Logger.getLogger(AbstractUsernamePasswordAuthenticationHandler.class);
/**
* 相关的数据库配置DS对应的jndi
*/
private String _jndi="jdbc/EmployeeDB";
/* (non-Javadoc)
* @see org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler#authenticateUsernamePasswordInternal(org.jasig.cas.authentication.principal.UsernamePasswordCredentials)
*/
public boolean authenticateUsernamePasswordInternal(
          final UsernamePasswordCredentials credentials) {
           String username = credentials.getUsername();
           String password = credentials.getPassword();
           log.info("username:"+username);
          
           log.info("password:"+password);
          try {
      password = MD5.encrypt(password);
      log.debug("md5password" + password);
     } catch (Exception e) {
      log.warn("MD5加密出错", e);
      //throw new Exception("MD5加密出错");
      return false;
     }
     /*
          if (StringUtils.hasText(username) && StringUtils.hasText(password)
              && username.equals(getPasswordEncoder().encode(password))) {
              getLog().debug(
                  "User [" + username + "] was successfully authenticated.");
              return true;
          }
          */
     try
     {
      if(checkuser(username,password)==1)
      {
       getLog().info("认证成功!");
       return true;
      }
     }
     catch(Exception e)
     {
      getLog().error("User [" + username + "] failed authentication",e);
     }
         
          return false;
      }
private int checkuser(String user, String pwd) throws Exception {
   int rei = 0;
   // Obtain our environment naming context
   log.debug("Obtain our environment naming context");
   Context initCtx = new InitialContext();
   Context envCtx = (Context) initCtx.lookup("java:comp/env");
   // Look up our data source
   DataSource ds = (DataSource) envCtx.lookup(this._jndi);
   log.debug("获取ds成功!");
   // Allocate and use a connection from the pool
   Connection conn = ds.getConnection();
   log.debug("获取conn成功!");
   // ... use this connection to access the database ...
   String sql = "select OPERATORID from operator where OPERATORLOGINNAME='"
     + user + "' and OPERATORPASSWORD='" + pwd + "' ";
   log.info("sql!= "+sql);
   Statement st = conn.createStatement();
   ResultSet rs = st.executeQuery(sql);
   if (rs.next()) {
    //String oid = rs.getString("OPERATORID");
    /*
    _op = new Operator(oid);
    _op.setName("操作员");
    _op.setLoginname(user);
    _op.setPwd(pwd);
    */
    rei = 1;
   } else {
    System.out.println("帐号不存在或密码错误!");
   }
   conn.close();
   return rei;
}
      /* (non-Javadoc)
       * @see org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler#afterPropertiesSetInternal()
       */
      protected void afterPropertiesSetInternal() throws Exception {
          super.afterPropertiesSetInternal();
          getLog()
              .warn(
                  this.getClass().getName()
                      + " is only to be used in a production environment.");
      }
}
 
F:ant 发布
G:运行调试
附录:ANT脚本
<?xml version="1.0" encoding="gb2312"?>
<project name="casself" default="release" basedir="." >
<property name="deployment.dir" value="C:/Program Files/Apache Software Foundation/Tomcat 5.5/webapps/cas/WEB-INF"/>
<!--<property name="deployment.dir" value="C:/casself"/-->
<target name="clean">
   <echo message="开始清除历史版本"/>
<delete> 
   <fileset dir=".">
    <include name="casself.jar"/>
   </fileset>
   <fileset dir="${deployment.dir}">
    <include name="web.xml"/>
    <include name="mydeployerConfigContext.xml"/>
    <include name="log4j.properties"/>
   
   </fileset>
</delete>
   </target>
<target name="compile">
<echo message="开始编译"/>
    <javac srcdir="." />
</target>
<target name="jar" depends="compile">
<echo message="开始打包"/>   
    <jar destfile="casself.jar"
         basedir="."
         includes="**/*.class"
         />
</target>
<target name="copy">
   <echo message="部署配置文件"/>
   <copy todir="${deployment.dir}">
      <fileset dir="./xml">
       <!--exclude name="**/doc/**"/-->
      </fileset>
    <fileset dir=".">
     <include name="log4j.properties"/>
    </fileset>
   </copy>
   <echo message="部署jar文件"/>
     <copy todir="${deployment.dir}/lib">
        <fileset dir=".">
        <include name="casself.jar"/>
        </fileset>
     </copy>
   </target>
<target name="release" depends="jar,copy">
   <echo message="release success!~"/>
    </target>
<target name="run" depends="jar">
    <java classname="hello"
          classpath="hello.jar"
          fork="true"
          />
</target>
</project>
 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics