当前位置:网站首页>XXL-SSO 实现SSO单点登录
XXL-SSO 实现SSO单点登录
2022-06-23 05:37:00 【zetor_major】
一、 概述:
本文旨在使用XXL-SSO开源架构 实现单点登录系统。
XXL-SSO 是一个分布式单点登录框架、只需要登录一次就可以访问所有相互信任的应用系统。
拥有”轻量级、分布式、跨域、Cookie+Token均支持、Web+APP均支持”等特性。现已开放源代码,开箱即用。
官网地址:https://www.xuxueli.com/xxl-sso/#/
二、 准备:
- 下载XXL-SSO
https://github.com/xuxueli/xxl-sso
https://gitee.com/xuxueli0323/xxl-sso
安装 xxl-sso-core-1.1.0.jar 到maven仓库:
mvn install:install-file -Dfile=D:/yourpath/xxl-sso-core-1.1.0.jar -DgroupId=com.xuxueli -DartifactId=xxl-sso-core -Dversion=1.1.0 -Dpackaging=jar
- 安装redis、并启动...
- 执行sql脚本:mysql创建用户表等相关操作,详细参考文末代码
三、实现单点登录服务端:
1)使用架构:
- springboot
- mybatisPlus for mysql
- swagger
- xxl-sso
2)代码参考如下:
- pom.xml
<!-- sso core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-sso-core</artifactId>
<version>1.1.0</version>
</dependency>
<!-- jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>XxlSsoConfig.java@Configuration public class XxlSsoConfig implements InitializingBean, DisposableBean { @Value("${xxl.sso.redis.address}") private String redisAddress; @Value("${xxl.sso.redis.expire.minite}") private int redisExpireMinite; @Override public void afterPropertiesSet() throws Exception { SsoLoginStore.setRedisExpireMinite(redisExpireMinite); SsoTokenLoginHelper.setRedisExpireMinite(redisExpireMinite); JedisUtil.init(redisAddress); } @Override public void destroy() throws Exception { JedisUtil.close(); } }- 登录页初始化
@RequestMapping(Conf.SSO_LOGIN)
public String login(Model model, HttpServletRequest request, HttpServletResponse response) {
// login check
XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);
if (xxlUser != null) {
// success redirect
String redirectUrl = request.getParameter(Conf.REDIRECT_URL);
if (redirectUrl != null && redirectUrl.trim().length() > 0) {
String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
return "redirect:" + redirectUrlFinal;
} else {
return "redirect:/";
}
}
// 查询账套(自定义查询)
List<TSystemSob> sobs = sysUserService.qrySobLst();
model.addAttribute("sobs", sobs);
model.addAttribute("errorMsg", request.getParameter("errorMsg"));
model.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
return "login";
}- 登录动作
@RequestMapping("/doLogin")
public String doLogin(HttpServletRequest request,
HttpServletResponse response,
RedirectAttributes redirectAttributes,
@RequestParam String username,
@RequestParam String password,
@RequestParam Integer sob,
String ifRemember) {
boolean ifRem = (ifRemember != null && "on".equals(ifRemember)) ? true : false;
redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
// valid login
TSysUser usr = sysUserMapper.qryOne(username, sob);
if (usr == null) {
redirectAttributes.addAttribute("errorMsg", "用户不存在!");
return "redirect:/login";
}
if (!Md5Util.isMatchPassword(password.trim(), usr.getPassword())) {
redirectAttributes.addAttribute("errorMsg", "用户名或密码错误!");
return "redirect:/login";
}
// 1、make xxl-sso user
XxlSsoUser xxlUser = new XxlSsoUser();
xxlUser.setUserid(String.valueOf(usr.getAccount()));
xxlUser.setUsername(usr.getRealName());
xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
xxlUser.setExpireMinite(SsoLoginStore.getRedisExpireMinite());
xxlUser.setExpireFreshTime(System.currentTimeMillis());
// 2、make session id
String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);
// 3、login, store storeKey + cookie sessionId
SsoWebLoginHelper.login(response, sessionId, xxlUser, ifRem, redisExpireMinite * 60);
// 4、return, redirect sessionId
String redirectUrl = request.getParameter(Conf.REDIRECT_URL);
if (redirectUrl != null && redirectUrl.trim().length() > 0) {
String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
return "redirect:" + redirectUrlFinal;
} else {
return "redirect:/";
}
}- 退出登录
@RequestMapping(Conf.SSO_LOGOUT)
public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
// logout
SsoWebLoginHelper.logout(request, response);
// del sessionData
removeStorageData(request);
redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
return "redirect:/login";
}- 登录页面( freemarker模板文件 )
<form action="${request.contextPath}/doLogin">
<div class="login-box-body">
<p class="login-box-msg">统一认证中心</p>
<div class="form-group has-feedback">
<input type="text" name="username" class="form-control" placeholder="Please input username."
value="admin" maxlength="50">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" name="password" class="form-control" placeholder="Please input password."
value="123456" maxlength="50">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="form-group">
<select class="form-control input-s-sm inline" name="sob">
<#list sobs as ss>
<option value="${ss.id}">${ss.sobName}</option>
</#list>
</select>
</div>
<#if errorMsg?exists>
<p style="color: red;">${errorMsg}</p>
</#if>
<div class="row">
<div class="col-xs-8">
<div class="checkbox icheck">
<label>
<input type="checkbox" name="ifRemember">记住密码
</label>
</div>
</div><!-- /.col -->
<div class="col-xs-4">
<input type="hidden" name="redirect_url" value="${redirect_url!''}"/>
<button type="submit" class="btn btn-primary btn-block btn-flat">Login</button>
</div>
</div>
</div>
</form>
四、实现客户端:
- 配置文件
@Configuration
public class XxlSsoConfig implements DisposableBean {
@Value("${xxl.sso.server}")
private String xxlSsoServer;
@Value("${xxl.sso.logout.path}")
private String xxlSsoLogoutPath;
@Value("${xxl.sso.excluded.paths}")
private String xxlSsoExcludedPaths;
@Value("${xxl.sso.redis.address}")
private String xxlSsoRedisAddress;
@Bean
public FilterRegistrationBean xxlSsoFilterRegistration() {
// xxl-sso, redis init
JedisUtil.init(xxlSsoRedisAddress);
// xxl-sso, filter init
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setName("XxlSsoWebFilter");
registration.setOrder(1);
registration.addUrlPatterns("/*");
registration.setFilter(new XxlSsoWebFilter());
registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer);
registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath);
registration.addInitParameter(Conf.SSO_EXCLUDED_PATHS, xxlSsoExcludedPaths);
return registration;
}
@Override
public void destroy() throws Exception {
// xxl-sso, redis close
JedisUtil.close();
}
}- 首页跳转
@RequestMapping("/")
public String index(Model model, HttpServletRequest request) {
XxlSsoUser xxlUser = (XxlSsoUser) request.getAttribute(Conf.SSO_USER);
model.addAttribute("xxlUser", xxlUser);
return "index";
}五、启动程序
启动顺序1. SSOServerApp、2.ClientApp
客户端port:8088
服务端port:8086
在浏览器地址栏输入:http://127.0.0.1:8088/client
完成跳转,如图

注:账套为本人自定义信息,可酌情删除。
用户名:admin 、密码:123456
登录成功:

六、备注:
以上即实现了xxl-sso架构的单点登录系统,由于架构较轻量,即功能性单一,不过扩展较方便。
本文在xxl-sso-core核心包中,做了几处简单修改,旨在实现登出跳转,打印log等功能,喜欢扩展的朋友可自行修改。

本文源码地址:
https://gitee.com/zetor2020/ym-paas-sso-xxl
下载代码的朋友点下star,多谢支持
![]()
点赞本文,再次感谢

边栏推荐
- Drawing and resetting of mars3d point, line and surface
- Haas506 2.0 development tutorial -hota (only supports versions above 2.2)
- 279.完全平方数
- 什么是客户体验自动化?
- Coordinate transformation
- haas506 2.0开发教程-hota(仅支持2.2以上版本)
- Data indicators and data analysis models that designers need to understand
- 将TensorFlow1.x改写为pytorch
- Linked Storage
- 30 data visualization tips that can not be ignored
猜你喜欢

haas506 2.0開發教程-高級組件庫-modem.sms(僅支持2.2以上版本)

如何查看本机IP

常见设置模式(抽象工厂&责任链模式&观察者模式)

从 WAN 到 SD-WAN 边缘设备的网络架构

Steam教育对国内大学生的影响力

Open source ecology 𞓜 super practical open source license basic knowledge literacy post (Part 2)

Sklearn classification in sklearn_ Report & accuracy / recall /f1 value

C语言学习总结

开源生态|超实用开源License基础知识扫盲帖(下)

Day_ 12 smart health project jasperreports
随机推荐
C# 获取DPI和真实分辨率的方式(可以解决一直是96的问题)
云盒子联合深信服,为南京一中打造智慧双模教学资源分享平台
百度URL參數之LINK?URL參數加密解密研究(代碼實例)
中台库存中的实仓与虚仓的业务逻辑设计
leetcode - 572. 另一棵树的子树
Steam教育对国内大学生的影响力
Qt 中 QVariant 使用总结
记一次GLIB2.14升级GLIB2.18的记录以及其中的步骤原理
279.完全平方数
C Advanced Learning -- Reflection
Sword finger offer 42 Maximum sum of successive subarrays
Index - MySQL
30 data visualization tips that can not be ignored
Haas506 2.0 development tutorial - Advanced Component Library -modem Sim (only supports versions above 2.2)
MySQL5.6 (5.7-8) 基于shardingsphere5.1.1 Sharding-Proxy模式读写分离
疫情下的传媒产业,小程序生态驱动数字化转型探索
Measurement principle and thickness measurement mode of spectral confocal
Coordinate transformation
Illuminate\support\collection de duplication unique list de duplication
There are so many code comments! I laughed