单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用系统中,用户只需一次登录就可以访问所有相互信任的应用系统。
例如:阿里系的系统,天猫,淘宝
SSO是一个理论,相当于java中的接口,接口就要有实现类,流行的SSO产品有OAuth2.0、CAS,OPENID、LDAP等。本教程对CAS进行讲解
2.1 OAuth 2.0OAuth 2.0是一个关于授权的开放网络协议,它允许用户让第三方网站访问该用户在某一网站上存储的信息和资源,如账户信息,照片,联系人等,而不需要给第三方网站提供某一网站上的账户和密码。
OAuth授权流程如下所述:
1、用户打开客户端,客户端要求授权。
2、用户同意客户端授权。
3、客户端使用上一步提供的授权,向服务器授权层申请令牌。
4、授权服务器对客户端进行认证后,同意发放令牌。
5、客户端使用令牌,向资源服务器申请资源。
6、资源服务器确认令牌,向客户端开放资源。
例如,访问网站可以使用QQ、微信快捷登录。
2.2 LDAPLDAP是一种基于轻量目录访问协议,全称是Lightweight Directory Access Protocol,是由一个为查询、浏览和搜索而优化的数据库构成,它成树状结构组织数据,类似文件目录一样。
LDAP单点登录认证主要是改变原有的认证策略,使得需要的软件都通过LDAP服务器进行认证,在统一身份认证后,用户的所有信息都存储在AD Server中,终端用户在需要使用公司内部服务的时候,都需要通过AD服务器进行认证。
整个LDAP登录流程由以下4个步骤组成:
1、连接到LDAP服务器。
2、绑定到LDAP服务器。
3、在LDAP服务器上执行所需要的操作。
4、释放LDAP服务器的连接。
LDAP主要用于企业内部,相当于LDAP作为一个中央数据库,存储了所有的用户信息,当登录公司系统时,进入LDAP进行用户检验。
2.3 CASCAS即Central Authentication Service模型(中央式认证服务),该协议是为应用提供可信身份认证的单点登录系统,最初是由耶鲁大学开发的。CAS 包含两个部分: CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。
二.CAS资源 1.官网:https://apereo.github.io/cas
2.github:https://github.com/apereo/cas
三.CAS原理分析 1.名词解释:TGC:存在浏览器的cookie中,当登录成功后CAS人中认证服务器创建
TGT:Ticket Granted Ticket,存在CAS认证服务器session中,登录成功后创建,并且在浏览器生成TGC
ST:Ticket Granted Ticket,TGT生成,在url中拼接
客户端:A:https://clientA.com; B:https://clientB.com
服务端:S:https://server.com;
1.浏览器第一次访问A,被web.xml中的org.jasig.cas.client.authentication.AuthenticationFilter过滤器拦截
2.AuthenticationFilter拦截后,判断session:中有没有_const_cas_assertion_,有就放行,没有再次判断
url中有没有url中有没有ticket,如果有放行,没有302重定向到登录页->https://server.com?service=https://clientA.com
3.跳转到服务器S,S判断没有TGC所以不能获取到TGT,跳转到认证登录页
4.认证页面输入用户名密码提交,S认证(密码策略可以自定义)
5.S认证通过后,生成Session:TGT和ST,并且根据TGT生成Cookie存在浏览器中,返回302重定向到A带上ST(ticket),生成的TGT是认证服务器地址的cookie
6.这时候重定向访问A带上了ticket,AuthenticationFilter拦截发现没有session:const_cas_assertion_但是有了ticket,然后交给TicketValidationFilter过滤器处理,验证ticket是否有效,如果有效,在A的Session中生成_const_cas_assertion,存入用户信息。
7.浏览器第二次访问A,也是被AuthenticationFilter过滤器拦截,判断session中是否有_const_cas_assertion_,有直接放行,实现了SSO
8.这时候再访问B,被AuthenticationFilter过滤器拦截,判断没有session:const_cas_assertion,没有ticket,302重定向到认证服务器S
9.认证服务器能够通过TGC找到TGT,所以是登录过的,根据TGT生成ST,302重定向到B
10.302访问B,B带上了ticket,AuthenticationFilter拦截发现没有session:const_cas_assertion,但是有了ticket,然后交给TicketValidationFilter过滤器处理,验证ticket是否有效,如果有效,在B的Session中生成_const_cas_assertion_,存入用户信息。
11.下一次访问B,也是被AuthenticationFilter过滤器拦截,判断session中是否有_const_cas_assertion_,有直接放行,实现了SSO
12.访问C…
CAS 5.x以下是基于Spring创建的,5.x以上是基于SpringBoot,6.x 基于JDK11,所以服务端版本选用5.x。
环境:jdk8+,maven,tomcat 9,idea
1.登录github。拉取cas-overlay-template,注意选择5.3
2.打开项目,新增src/main/java和src/main/resources,并将overlays目录下的META-INF、services、static、templates、application.properties和log4j2.xml拷贝到resources目录下
3.执行mvn clean,mvn package,打包cas.war
2.生成SSL证书因为CAS服务端只支持https请求,所以需要ssl证书,证书需要购买,但是测试环境可以用keytool生成测试证书
生成证书过程具体百度
打开tomcat/conf/server.xml,增加8443的ssl配置
keystoreFile:证书路径
keystorePass:证书密码
cas回调客户端默认不支持http,所以需要增加http的支持。
修改WEB-INF/classes/services/HTTPSandIMAPS-10000001.json 的serviceId,增加http
打开hosts文件,增加域名映射,注意域名要和创建证书的姓名一致
6.启动服务sh startup.sh 启动tomcat
浏览器输入https://域名:8443/cas,显示登录界面,默认登录名在application.properties中:
cas.authn.accept.users=casuser::Mellon
用户名:casuser
密码:Mellon
输入用户名和密码点击登录,弹出登录成功证明服务端创建成功
五.CAS服务端集成JDBC 1.增加pom依赖2.修改配置文件org.apereo.cas cas-server-support-jdbc ${cas.version} org.apereo.cas cas-server-support-jdbc-drivers ${cas.version} mysql mysql-connector-java 8.0.12
打开application.properties,增加jdbc配置
#jdbc配置 #添加jdbc认证 cas.authn.jdbc.query[0].sql=SELECt * FROM userinfo WHERe username =? #哪一个字段作为密码字段 cas.authn.jdbc.query[0].fieldPassword=password #配置数据库连接 cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/ceshi?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false #cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect #数据库用户名 cas.authn.jdbc.query[0].user=dou #数据库密码 cas.authn.jdbc.query[0].password=douxuwang #mysql驱动 cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver #默认加密策略,通过encodingAlgorithm来指定算法,默认NONE不加密 #cas.authn.jdbc.query[0].passwordEncoder.type=com.cbhb.encoder.MyEncoder #cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8 #cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD53.密码加密 1.CAS自带加密算法
如果数据库密码需要加密需要配置
#默认加密策略,通过encodingAlgorithm来指定算法,默认NONE不加密 #cas.authn.jdbc.query[0].passwordEncoder.type=com.cbhb.encoder.MyEncoder cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8 cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5 例如 cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD52.自定义加密算法
如果数据库的密码是自定义的加密算法存储的可以进行如下配置
1.创建自定义密码策略类创建自定义需要策略类,需要实现PasswordEncoder接口
package com.cbhb.encoder;
import org.springframework.security.crypto.password.PasswordEncoder;
public class MyEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence) {
return EncryptUtil.encrypt(charSequence.toString());
}
@Override
public boolean matches(CharSequence charSequence, String s) {
try {
String decrypt = EncryptUtil.decrypt(s);
return decrypt.equals(charSequence.toString());
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
2.修改配置文件
修改application.properties文件,增加自定义的密码策略类
cas.authn.jdbc.query[0].passwordEncoder.type=com.cbhb.encoder.MyEncoder3.打war包
mvn clean,mvn package
4.替换war包并重启替换tomact下的cas.war并重启
六.CAS服务端集成LDAP待续。。。



