CAS Server 4.2.7(自定义密码验证) 部署

1.  制作及配置安全证书

1)   制作SSL证书

过程不多说,相关资料很多。域名暂定为cas.example.com。证书存放至服务器相关目录,假设为E:HTTPSserverserver.keystore,制作证书时的密码假设为ssl_password。

2)   修改host

用文本编辑器修改C:WindowsSystem32Driversetchost文件,在最后添加一行:

cas.example.com	127.0.0.1

3)   配置tomcat

修改tomcat的server.xml配置文件,在其中添加:

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
       maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
       clientAuth="false" sslProtocol="TLS"
       keystoreFile="E:HTTPSserverserver.keystore" keystorePass="ssl_password"
       truststoreFile="E:HTTPSserverserver.keystore" truststorePass="ssl_password"
  />

2.  部署cas server 4.2.7

将cas-server-webapp-4.2.7.war拷贝到Tomcat的webapps目录,改名(假设为cas.war);启动Tomcat后,自动解压为cas目录,此时建议删除或移走cas.war。

拷贝以下jar文件至cas/WEB-INF/lib目录:

  •  cas-server-support-jdbc-4.2.7.jar
  •  cas-server-support-rest-4.2.7.jar
  •  ojdbc6.jar或ojdbc7.jar
  •  cas_custom_auth_handler.jar(自定义密码验证模块)

3.  修改cas server配置

主要是针对两个配置文件deployerConfigContext.xml和cas.properties的修改,均在cas/WEB-INF目录下。

1)   增加数据源

修改deployerConfigContext.xml,添加:

   <bean id="dataSource"
      class="com.mchange.v2.c3p0.ComboPooledDataSource"
      p:driverClass="oracle.jdbc.driver.OracleDriver"
      p:jdbcUrl="jdbc:oracle:thin:@localhost:orcl"
      p:user="oracle"
      p:password="oracle"
      p:initialPoolSize="6"
      p:minPoolSize="6"
      p:maxPoolSize="18"
      p:maxIdleTimeExcessConnections="120"
      p:checkoutTimeout="10000"
      p:acquireIncrement="6"
      p:acquireRetryAttempts="5"
      p:acquireRetryDelay="2000"
      p:idleConnectionTestPeriod="30"
      p:preferredTestQuery="select 1" />

2)   修改密码认证方式

修改deployerConfigContext.xml,注释掉原来的primaryAuthenticationHandler,改为:

<!--<alias name="acceptUsersAuthenticationHandler" alias="primaryAuthenticationHandler" />-->
<alias name=" casCustomAuthenticationHandler" alias="primaryAuthenticationHandler" />
<bean id="casCustomAuthenticationHandler"
    class="com.example.cas_custom_auth_handler.CasCustomAuthenticationHandler" />
<alias name="dataSource" alias="queryDatabaseDataSource" />

3)   修改获取密码的sql

对cas.propeities进行修改,去掉“cas.jdbc.authn.query.sql=”前的注释符,改为适合项目的语句,比如:

cas.jdbc.authn.query.sql=select l.password from user_role r, user_login l where r.user_id=? and r.id=l.id

初始的默认用户已经不再有效,可以注释掉(可选,不影响):

#accept.authn.users=casuser::Mellon

4)   允许注销后可重定向(可选)

修改cas.propeities,去掉“cas.logout.followServiceRedirects=false”前的注释符,改为:

cas.logout.followServiceRedirects=true

5)   修改TGT为永不失效策略

修改deployerConfigContext.xml,注释掉原来的grantingTicketExpirationPolicy,修改为:

<!--<alias name="ticketGrantingTicketExpirationPolicy" alias="grantingTicketExpirationPolicy" />-->
<alias name="neverExpiresExpirationPolicy" alias="grantingTicketExpirationPolicy" />

4.  自定义密码验证模块

这里用我们自定义的密码验证模块cas_custom_auth_handler取代了CAS Server提供的标准验证模块,以下是它的实现代码:

package com.example.cas_custom_auth_handler;

import java.security.GeneralSecurityException;

import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import javax.sql.DataSource;
import javax.validation.constraints.NotNull;

import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.stereotype.Component;

@Component("casCustomAuthenticationHandler")
public class CasCustomAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler
{
    @NotNull
    private String sql;

    @Override
    protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential)
            throws GeneralSecurityException, PreventedException
    {
        if (this.sql.isEmpty() || getJdbcTemplate() == null)
        {
            throw new GeneralSecurityException("Authentication handler is not configured correctly.");
        }

        String username = credential.getUsername();
        String password = credential.getPassword();

        try
        {
            //String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
            String dbPassword = ... // your encryting code here
            if (!password.equals(dbPassword))
                throw new FailedLoginException("Password does not match value on record.");
        }
        catch (final IncorrectResultSizeDataAccessException e)
        {
            if (e.getActualSize() == 0)
                throw new AccountNotFoundException(username + " not found with SQL query.");
            else
                throw new FailedLoginException("Multiple records found for " + username);
        }
        catch (DataAccessException e)
        {
            throw new PreventedException("SQL exception while executing query for " + username, e);
        }
        return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
    }

    /**
     * @param sql: The sql to set.
     */
    @Autowired
    public void setSql(@Value("${cas.jdbc.authn.query.sql:}") final String sql)
    {
        this.sql = sql;
    }

    @Override
    @Autowired(required = false)
    public void setDataSource(@Qualifier("queryDatabaseDataSource") final DataSource dataSource)
    {
        super.setDataSource(dataSource);
    }

}
原文地址:https://www.cnblogs.com/wggj/p/7550361.html