背景:公司需要建一个平台类型的项目,供多个系统共同使用,且各个系统使用各自的单点登录。这几个系统使用的都是cas进行单点登录。
解决方案:使用cas,进行服务端的跳转和通知。
1、建立sessionId和请求系统标识位之间的关系。
2、根据关系,区分系统,利用cas自己特有的sessionId和cookie携带用户登录信息去认证各自的登录。
3、平台系统建立自己的用户权限管理功能。
针对cas的路径和ticket校验,主要重写的cas类
MyCasAuthenticator :根据请求路径携带的服务端标识码进行ticket校验路径拼接替换
public class MyCasAuthenticator extends CasAuthenticator {
@Override
public void validate(final TokenCredentials credentials, final WebContext context) throws HttpAction {
//todo
1、根据业务逻辑需要建立权限认证的唯一标识(sessionId )和访问系统表示之间的关系
2、返回对应的callbackUrl,重写valiadate方法,并进行路径匹配的校验
final Assertion assertion = new MyAbstractUrlBasedTicketValidator(ResourcesUtil.casServerUrlPrefix()).validateNew(ticket, finalCallbackUrl,repalceUrl);
}
}
MyAbstractUrlBasedTicketValidator :重写Ticket校验拼接服务端路径校验器
public class MyAbstractUrlBasedTicketValidator extends Cas30ServiceTicketValidator {
public Assertion validateNew(final String ticket, final String service,String loginUrl ) throws TicketValidationException {
//todo实现自己的校验方法
使得 ticket拼接的validationurl一致,请求对应的单点,返回正确的验证结果并可以拿到正确的用户信息
}
}
MyDefaultWebSessionManager : 初始化sessionId和需要单点登录的服务端之间的关系
protected void onStart(Session session, SessionContext context) {
//监听初始化事件,根据路径上的请求参数,建立第一次请求时sessionId和请求系统之间的对应关系。以便在校验阶段根据sessionId进行路径拼接
if (isSessionIdCookieEnabled()) {
Serializable sessionId = session.getId();
storeSessionId(sessionId, request, response);
String 请求系统表示代码= request.getParameter("请求系统表示参数");
if (StringUtils.isNotBlank(请求系统表示代码)){
RedisClusterUtil.getInstance().set("缓存keyprefix:"+sessionId ,请求系统表示代码);
}
} else {
log.debug("Session ID cookie is disabled. No cookie has been set for new session with id {}", session.getId());
}
}