单点登录
第一步,获取单点服务
1.网上的开源服务很多,随便找一个,比如我是在gitee上拉的做了一些改动
了解单点流程
编写校验代码
最主要的就是要校验ticket
我的代码如下,仅供参考:
、、、
@GetMapping("/validateLogin")
public Object validateLogin(@RequestParam(name="ticket") String ticket,
@RequestParam(name="service") String service,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
Result<JSONObject> result = new Result<JSONObject>();
log.info("Rest api login.");
try {
String validateUrl = prefixUrl+"/p3/serviceValidate"; //cas的校验地址
String res = CasServiceUtil.getStValidate(validateUrl, ticket, service);
log.info("res."+res);
final String error = XmlUtils.getTextForElement(res, "authenticationFailure");
if(StringUtils.isNotEmpty(error)) {
throw new Exception(error);
}
final String principal = XmlUtils.getTextForElement(res, "user");
if (StringUtils.isEmpty(principal)) {
throw new Exception("验证不成功");
}
log.info("-------token----username---"+principal);
//1. 校验用户是否有效
SysUser sysUser = sysUserService.getUserByName(principal);
result = sysUserService.checkUserIsEffective(sysUser);
if(!result.isSuccess()) {
return result;
}
//自己的登录逻辑我就不展示了
result.setResult(obj);
result.success("登录成功");
} catch (Exception e) {
//e.printStackTrace();
result.error500(e.getMessage());
}
return new HttpEntity<>(result);
}
这样就可以实现登录了。
统一退出
退出的时候cas服务器会向注册进去的服务发送退出请求,所以我们写一个拦截器就好了
/**
* 该过滤器用于实现单点登出功能,可触发服务端退出时,所有客户端的退出效果。
* 单点退出配置,一定要设置优先级
*/
@SneakyThrows
@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
// 转换参数
final HttpServletRequest request = (HttpServletRequest) servletRequest;
//判断参数中是否具有artifactParameterName属性指定的参数名称,默认是ticket
String logoutRequest = request.getParameter("logoutRequest");
if (logoutRequest!=null) {
String ticket = XmlUtils.getTextForElement(logoutRequest, "SessionIndex");
String token = (String)redisUtil.get(CommonConstant.PREFIX_USER_TOKEN + ticket);
String username = JwtUtil.getUsername(token);
SysUser sysUser = sysUserService.getUserByName(username);
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + ticket);
redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
SecurityUtils.getSubject().logout();
return;
} else {
log.trace("Ignoring URI " + request.getRequestURI());
}
//条件都不满足,继续执行下面的过滤器
filterChain.doFilter(servletRequest, servletResponse);
}
每个人的退出逻辑不一样的,自己实现。
cas退出配置
我们要保证服务能被通知,那么就要先注册进去
配置如下所示:
一定要在service路径
这是配置
然后就全盘搞定啦,如有问题可以咨询