CasServer在windows上的源码编译和打包部署(4.2.7版本)

直接上过程:

1.  下载cas-overlay-template源码

https://github.com/apereo/cas/releases/tag/v4.2.7


选择Maven的Overlay源码

下载zip包并解压到本地,如果有github的客户端也可以选择open in desktop,克隆到本地

2.  使用eclipse或者IDEA导入Maven项目,之后等待自动下载依赖项,下载完成之后继续

3.  展开src\main\webapp\WEB-INF\spring-configuration,项目中已提供propertyFileConfigurer.xml的覆盖文件,是配置cas.properties文件路径的配置文件,默认是file:etc/cas/cas.properties,注意,该路径是linux的路径,如果是在windows上部署,需要改为file:D:\\webserver\\cas\\cas.properties这样的路径才可以,注意路径前面的file:不能丢,否则会报找不到cas.properties文件的错误

然后将项目下的etc目录中的cas.properties文件拷贝到配置的路径中备用

4.  Overlay的用法说明:

Overlay的意思就是覆盖文件,即如果是配置文件则覆盖相同目录中的文件,如果是类文件则编译后覆盖相同包中的类class文件,如果是新文件则添加到相应的目录中。

展开overlays目录

 

这是我本地已经覆盖过的文件和添加的类文件,可以看到的是src\main\webapp\WEB-INF目录下的子目录和文件(从overlays中拷贝的)与overlays中的是一致的,这样打包后src中的文件就会覆盖overlays中的同名文件。类文件的包名可以自定义,打包后会自动编译,使用方式后面会说明。

5.  下面开始说修改的内容

a)  修改cas.properties文件路径,编辑src\main\webapp\WEB-INF\spring-configuration\propertyFileConfigurer.xml文件,之前已说过不再赘述。

b)  启用http访问的支持

         i.  修改D:\webserver\cas.properties文件

tgc.securewarn.cookie.secure都改为false,,默认是true也就是https

          ii.   覆盖HTTPSandIMAPS-10000001.json文件

编辑复制的json文件

serverId增加http方式

    c)  修改cas的认证方式,密码校验改为数据库方式

          i.  编辑pom.xml,增加数据库访问依赖

            dependencies中增加以下三个依赖

        <dependency>

           <groupId>org.jasig.cas</groupId>

           <artifactId>cas-server-support-jdbc</artifactId>

           <version>${cas.version}</version>

       </dependency>

       <dependency>

           <groupId>mysql</groupId>

           <artifactId>mysql-connector-java</artifactId>

           <version>6.0.6</version>

       </dependency>

        <dependency>

           <groupId>com.alibaba</groupId>

           <artifactId>druid</artifactId>

           <version>1.0.16</version>

       </dependency>

    数据库用的是mysql,连接池用的是druid,也可以换成别的。需要注意的是,mysql connector6.0以上版本的driveClassName用的是com.mysql.cj.jdbc.Driver,连接字符串也需要增加serverTimezone=UTC否则会报错

    jdbc:mysql://localhost:3306/accountdb?characterEncoding=utf-8&amp;serverTimezone=UTC,中间的&符号必须用HTML的转义符,否则也会报错

         ii.  修改用户认证方式

        编辑deployerConfigContext.xml

        

        编辑新复制的deployerConfigContext.xml

        

        注释的代码:<aliasname="acceptUsersAuthenticationHandler"alias="primaryAuthenticationHandler" />

        增加的代码:

        <alias name="customQueryDatabaseAuthenticationHandler"alias="primaryAuthenticationHandler" />

 <bean id="dataSource"class="com.alibaba.druid.pool.DruidDataSource"init-method="init" destroy-method="close">

    <property name="url"

        value="jdbc:mysql://localhost:3306/accountdb?characterEncoding=utf-8&amp;serverTimezone=UTC"/>

        <property name="username"value="root" />

        <property name="password"value="1234" />

        <property name="driverClassName"value="com.mysql.cj.jdbc.Driver"/>

        <propertyname="validationQueryTimeout" value="10000" />

        <propertyname="initialSize" value="1" />

        <property name="minIdle"value="1" />

        <property name="maxActive"value="10" />

        <property name="maxWait"value="10000" />

        <propertyname="timeBetweenEvictionRunsMillis" value="60000" />

        <propertyname="minEvictableIdleTimeMillis" value="300000" />

        <property name="testWhileIdle"value="true" />

        <propertyname="poolPreparedStatements" value="true" />

        <propertyname="maxPoolPreparedStatementPerConnectionSize"   value="20" />

        <propertyname="defaultAutoCommit" value="true" />

        <propertyname="validationQuery" value="select 1 " />

        <!-- 超过时间限制是否回收-->

        <propertyname="removeAbandoned" value="true" />

        <!-- 超时时间;单位为秒。180=3分钟-->

        <propertyname="removeAbandonedTimeout" value="30" />

        <!-- 关闭abanded连接时输出错误日志 -->

        <property name="logAbandoned"value="true" />

        </bean>

        <alias name="dataSource"alias="queryDatabaseDataSource"/>

        注:customQueryDatabaseAuthenticationHandler这个bean是自定义的Handler类,使用了@Component注解设置的beanName

        编辑cas.properties文件

        

        cas.jdbc.authn.search.user=XXX  //数据库的查询用户

        cas.jdbc.authn.search.password=XXX  //数据库查询用户的密码

        cas.jdbc.authn.query.sql=SELECT password FROM `user`WHERE userName=?  //自定义的SQL,根据用户名查询密码

        cas.jdbc.authn.query.encode.salt=XXX  //密码加密的“盐”,可以为空,根据数据库中密码的生成规则有关

                  

        新建自定义身份认证类和密码加密类

                   src\main目录下新建java目录,然后新建package

                  

                  

CustomPasswordEncoder.java

 

package org.jasig.cas.adaptors.jdbc;

 

import org.apache.shiro.crypto.RandomNumberGenerator;

import org.apache.shiro.crypto.SecureRandomNumberGenerator;

import org.apache.shiro.crypto.hash.SimpleHash;

import org.apache.shiro.util.ByteSource;

public classCustomPasswordEncoder {

    private RandomNumberGeneratorrandomNumberGenerator = null;

    private String algorithmName ="sha";

    private int hashIterations = 2;

    public CustomPasswordEncoder() {

        randomNumberGenerator = newSecureRandomNumberGenerator();

    }

    public RandomNumberGeneratorgetRandomNumberGenerator() {

        return randomNumberGenerator;

    }

   public void setRandomNumberGenerator(RandomNumberGeneratorrandomNumberGenerator) {

        this.randomNumberGenerator =randomNumberGenerator;

    }

    public String getAlgorithmName() {

        return algorithmName;

    }

    public void setAlgorithmName(StringalgorithmName) {

        this.algorithmName = algorithmName;

    }

    public int getHashIterations() {

        return hashIterations;

    }

    public void setHashIterations(inthashIterations) {

        this.hashIterations = hashIterations;

    }

    public String encrypt(String value, Stringsalt) {

        return new SimpleHash(algorithmName,value, ByteSource.Util.bytes(salt), hashIterations).toHex();

    }

}

CustomQueryDatabaseAuthenticationHandler.java

 

packageorg.jasig.cas.adaptors.jdbc;

 

importorg.apache.commons.lang3.StringUtils;

importorg.apache.shiro.dao.DataAccessException;

importorg.jasig.cas.authentication.HandlerResult;

importorg.jasig.cas.authentication.PreventedException;

importorg.jasig.cas.authentication.UsernamePasswordCredential;

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.beans.factory.annotation.Qualifier;

importorg.springframework.beans.factory.annotation.Value;

importorg.springframework.dao.IncorrectResultSizeDataAccessException;

importorg.springframework.stereotype.Component;

 

import javax.security.auth.login.AccountNotFoundException;

importjavax.security.auth.login.FailedLoginException;

importjavax.sql.DataSource;

importjavax.validation.constraints.NotNull;

importjava.security.GeneralSecurityException;

importjava.util.Map;

 

/**

 * 使用了@Component注解并设置beanName,在deployerConfigContext.xml中使用

 */

@Component("customQueryDatabaseAuthenticationHandler")

public classCustomQueryDatabaseAuthenticationHandler

        extendsAbstractJdbcUsernamePasswordAuthenticationHandler {

 

    @NotNull

private String sql;

 

//cas.properties中读取加密盐

    @Value("${cas.jdbc.authn.query.encode.salt}")

    private String salt;

 

    @Override

protected HandlerResult authenticateUsernamePasswordInternal(

UsernamePasswordCredential transformedCredential)

            throws GeneralSecurityException,PreventedException {

        if (StringUtils.isBlank(this.sql) ||null == getJdbcTemplate()) {

            throw newGeneralSecurityException("Authentication handler is not configuredcorrectly");

        }

 

        String userName =transformedCredential.getUsername();

        try {

            Map<String, Object> resultMap= getJdbcTemplate().queryForMap(this.sql, userName);

            String userPassword =resultMap.get("password").toString();

            String inputPassword =transformedCredential.getPassword();

            CustomPasswordEncoder encoder = newCustomPasswordEncoder();

            String encryptPassword =encoder.encrypt(inputPassword, salt);

            if(!userPassword.equals(encryptPassword)) {

                throw newFailedLoginException("Password does not match value on record.");

            }

        } catch(IncorrectResultSizeDataAccessException e) {

            if (e.getActualSize() == 0) {

                throw new AccountNotFoundException(userName+ " not found with SQL query");

            } else {

                throw newFailedLoginException("Multiple records found for " + userName);

            }

        } catch (DataAccessException e) {

            throw newPreventedException("SQL exception while executing query for " +userName, e);

        }

 

        returncreateHandlerResult(transformedCredential,

this.principalFactory.createPrincipal(userName), null);

    }

 

    @Autowired

    public void setSql(@Value("${cas.jdbc.authn.query.sql}")final String sql) {

        this.sql = sql;

    }

 

    @Override

    @Autowired(required = false)

    public voidsetDataSource(@Qualifier("queryDatabaseDataSource") DataSourcedataSource) {

        super.setDataSource(dataSource);

    }

}

以上两个类的原创地址:http://www.cnblogs.com/wggj

至此配置自定义身份认证方式完毕!

现在可以使用eclipse或者IDEA进行打war包了,打包完之后将target目录中的cas.war丢到tomcat中运行即可。

d)  解决一个log4j.xml找不到的问题

默认情况下,log4j.xml是被排除在war包中的,运行后会报一个找不到log4j.xml的错误。log4j.xml的部署配置是在pom.xml

把这一行注释掉即可。

e)  设置casweb页面的默认语言

编辑新复制的applicationContext.xml文件,增加以下代码

<util:listid="basenames">

       <value>classpath:custom_messages</value>

       <value>classpath:messages_zh_CN</value>

</util:list>

messages_zh_CN是一个properties文件,项目build之后war包中的classes目录下会有各种语言的properties文件

f)  修改cas默认的登录页面

如果使用http方式,就需要注释掉一些安全警告内容,编辑新复制的casLoginView.jsp文件

把这段注释<%-- --%>掉即可。另外,修改UI布局和样式也是直接修改此页面。其他页面如注销页面casLogoutView.jsp也可以同样方式操作。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页