天天看点

JFinal整合CAS实现SSO单点登陆(服务端)

  • 生成server key及证书

生成server key

命令行运行如下命令

keytool -genkey -alias key_name -keyalg RSA -keypass 123456 -storepass 123456  -dname "CN=www.mycas.com,OU=csoa,O=csoa,L=FZ,ST=FZ,C=CN" -ext san=ip:192.168.2.121   -validity 3600  -keystore changename.keystore
           

命令解释:(以上所有命令和参数之间都有空格,每个命令之间也有空格)

-genkey 为生成key的指令

-alias key_name 为指定key的别名,在导入导出证书时会用到

-keyalg RSA 为指定key的加密算法,为默认算法

-keypass 123456 为指定证书密码,即后续在tomcat中配置的密码

-storepass 123456 为指定密钥库的密码,即jre/lib/security/cacerts密钥库的密码,在导入导出证书时需要用到

密钥库和证书的区别就像是tomcat容器和里面装载的application的区别,也就是你登陆了tomcat你就可以对所有的application进行管理(例如deploy,delete),但是你要使用application就必须有application本身对应的密码

-dname "CN=www.mycas.com,OU=csoa,O=csoa,L=FZ,ST=FZ,C=CN" 为指定下面截图内容

JFinal整合CAS实现SSO单点登陆(服务端)

其中最重要的是“名字与姓氏”,只能使用域名(未测试使用IP时的所有情况,但大部分情况都无法成功),其它的随便填即可

-ext san=ip:192.168.2.121 为指定上述域名所使用的主题备用名称(Subject Alternative Name, SAN),可指定为IP,这样就能使用IP来访问CAS服务端和客户端

-validity 3600 指定密钥默认的有效期,单位是天

-keystore changename.keystore 指定生成文件的文件名

导出证书

keytool -export -trustcacerts -alias tomcat_key -file client.cer -keystore server.keystore -storepass changeit
           

这里用到的tomcat_key、server.keystore、changeit、client.cer分别对应上述描述中的key别名、server key文件名、密钥库密码、导出的证书文件名

生成的证书,必须在每个客户端的服务器使用的JRE中导入,这样才能够保证双方完成协议握手,否则会抛出异常

  • 部署CAS默认项目

​​​​​​部署项目

将cas-server-webapp-4.2.5.war复制到服务端tomcat下,并修改名称为cas.war(方便浏览器访问)

注:服务器tomcat也和客户端tomcat一样,需要修改tomcat配置文件,详情见客户端手册第二大点

访问CAS主页及登陆

启动tomcat,待正常启动后(无报错),访问https://localhost:8443/cas

如果出现证书非法等字样,点高级选项继续访问即可

例如火狐会出现如下提示

JFinal整合CAS实现SSO单点登陆(服务端)

点高级,接受风险并继续即可

JFinal整合CAS实现SSO单点登陆(服务端)

这样就进入了CAS的主页

JFinal整合CAS实现SSO单点登陆(服务端)

当然也可以访问http页面,http://localhost:8087/cas/,这样就不会出现证书不被信任的情况,但是首页会有不安全连接提示

JFinal整合CAS实现SSO单点登陆(服务端)

我们输入用户名casuser密码Mellon即可登陆成功

JFinal整合CAS实现SSO单点登陆(服务端)
  • 修改CAS登陆配置-使用数据库表登陆

修改CAS配置文件

关掉tomcat,删除cas.war(必须先关掉tomcat再删除否则项目文件夹也会自动删除),然后进入项目文件夹cas/WEB-INF/目录,找到deployerConfigContext.xml文件

详情可见对应的配置文件,可以直接用它覆盖源文件,下面是对添加的配置的说明

在<util:map id=”authenticationHandlersResolvers”>中添加一行

<entry key-ref="databaseAuthenticationHandler" value-ref="primaryPrincipalResolver" />
           
JFinal整合CAS实现SSO单点登陆(服务端)

其中第二条entry是默认的登陆方式(casuser/Mellon),如果不想用户以这种方式登陆,则可以去掉第二条entry,第三条entry是我们自己定义的校验方式,其中key-ref是我们自己定义的bean or alias,名字可以随便起,而value-ref是默认的校验Resolver,不需要改

在<alias name="personDirectoryPrincipalResolver" alias="primaryPrincipalResolver" />下面添加如下内容

     <bean name="queryDatabaseAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">

         <property name="dataSource" ref="dataSource"></property>

         <property name="sql" value="select password from t_sys_user where username = ?"></property>

         <property name="passwordEncoder" ref="defaultPasswordEncoder"></property>

     </bean>
           

这个是我们自己定义的登陆验证bean,指定的class是CAS提供的一个默认实现,用来实现用户名密码的校验过程,源码文件可以自行查看源码目录中的文件,其中的sql可以自行根据需要修改,如果要修改sql的返回值,那么必须得修改QueryDatabaseAuthenticationHandler文件中的逻辑代码,同样的,其属性passwordEncoder也是CAS提供的一个默认实现,用来实现对密码加密的过程(数据库存密文),如果需要对明文进行匹配,那么可以选择修改密码校验的QueryDatabaseAuthenticationHandler或者DefaultPasswordEncoder

       <alias name="queryDatabaseAuthenticationHandler" alias="databaseAuthenticationHandler" />

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

这个是定义的别名,就是一个引用的关系

     <bean id="dataSource"

           class="com.mchange.v2.c3p0.ComboPooledDataSource"

           p:driverClass="${cas.audit.database.driverClass}"

           p:jdbcUrl="${cas.audit.database.url}"

           p:user="${cas.audit.database.user}"

           p:password="${cas.audit.database.password}"

           p:initialPoolSize="${cas.audit.database.pool.minSize}"

           p:minPoolSize="${cas.audit.database.pool.minSize}"

           p:maxPoolSize="${cas.audit.database.pool.maxSize}"

           p:maxIdleTimeExcessConnections="${cas.audit.database.pool.maxIdleTime}"

           p:checkoutTimeout="${cas.audit.database.pool.maxWait}"

           p:acquireIncrement="${cas.audit.database.pool.acquireIncrement}"

           p:acquireRetryAttempts="${cas.audit.database.pool.acquireRetryAttempts}"

           p:acquireRetryDelay="${cas.audit.database.pool.acquireRetryDelay}"

           p:idleConnectionTestPeriod="${cas.audit.database.pool.idleConnectionTestPeriod}"

           p:preferredTestQuery="${cas.audit.database.pool.connectionHealthQuery}" />
           

这是自定义数据源bean,和spring里面自定义数据源是一模一样的,${}是表示引用的变量,变量保存在cas.properties文件中

JFinal整合CAS实现SSO单点登陆(服务端)

同样登陆验证bean中的sql也可以使用变量的方式配置在此配置文件中

修改配置支持http协议

找到classes/services/目录下的HTTPSandIMAPS-10000001.json文件,用编辑器打开后,修改第二行 

"serviceId" : "^(https|imaps|http)://.*",
           

即可让CAS支持客户端认证登陆时的http协议及请求,当然如果还有FTP请求也可以在这里添加,只是一般无需通过FTP请求认证登陆

修改登陆验证代码

新建web项目,将CAS/WEB-INF/lib目录下所有jar包导入,将源码中的QueryDatabaseAuthenticationHandler.java拷贝到项目文件夹下,注意要带全路径,建议直接拷贝该文件所在的父级文件夹java下的所有文件

JFinal整合CAS实现SSO单点登陆(服务端)

例如这里是定位到java目录,然后把整个org文件夹复制到src目录下,形成如下目录结构

JFinal整合CAS实现SSO单点登陆(服务端)

必须这样设置目录结构,一是确保文件导入进来的时候不会报错(package路径问题),二是修改完毕后需要覆盖原jar包中的class文件,所以必须能够正常编译,如果有错误是无法正常编译的

打开该文件,将第47行注释,写入我们自己的代码

JFinal整合CAS实现SSO单点登陆(服务端)
JFinal整合CAS实现SSO单点登陆(服务端)

这里是因为我们的密码存的明文,所以直接拿页面参数(credential)中的password和数据库中密码比对即可,无需进行加密操作,全部修改完毕后,重启服务端tomcat即可

继续阅读