XXL-SSO分布式框架主要优点之一是对Cookie、Token均支持。
下面直接从github上克隆官方demo
(https://github.com/xuxueli/xxl-sso.git)
SSO Server(授权认证中心)
config | interceptor | resolver | AppController | WebController | core | service |
---|---|---|---|---|---|---|
配置 | 过滤器 | 全局异常捕获 | App访问控制层 | Web访问控制层 | 相关实体类 | 用户信息验证服务 |
需要检查下application.properties中的redis配置,将logback.xml的log.path属性路径值,建议改成./log/xxl-sso-server.log。
SSO Client应用(Cookie形式)
检查application.properties中的redis,以及xxl.sso.server值如设为http://xxlssoserver.com:8080/xxl-sso-server
在mac系统上通过vim /etc/hosts命令添加映射:
localhost xxlssoserver.com
127.0.0.1 xxlssoserver.com
Server和Client端都启动完毕后
访问Client地址后跳转至统一认证中心
http://xxlssoserver.com:8080/xxl-sso-server/login?redirect_url=http://127.0.0.1:8091/xxl-sso-web-sample-springboot/
为了看到单点登录的效果,可以再复制出一个Client工程,设置其他端口启动,并配置hosts域名映射。(拷贝微服务子工程,要额外改设置)
redis已保存sessionid信息
其中,sessionid生成片段代码:
// 2.生成用户令牌Key
String keyPrefix = Constants.MEMBER_TOKEN_KEYPREFIX + loginType;
UserTokenDo userTokenDo = userTokenMapper.selectByUserIdAndLoginType(userId, loginType);
if (userTokenDo != null) {
// 如果登陆过 清除之前redistoken
String oriToken = userTokenDo.getToken();
userTokenMapper.updateTokenAvailability(oriToken);
}
// 4.将用户生成的令牌插入到Token记录表中
UserTokenDo userToken = new UserTokenDo();
userToken.setUserId(userId);
userToken.setLoginType(userLoginInpDTO.getLoginType());
String newToken = keyPrefix + UUID.randomUUID().toString().replace("-", "");
userToken.setToken(newToken);
userToken.setDeviceInfor(deviceInfor);
userTokenMapper.insertUserToken(userToken);
userDo.setToken(newToken);
BaseResponse<UserLoginInOutDTO> login = memberLoginServiceFeign.ssoLogin(userLoginInpDTO);
if (!isSuccess(login)) {
setErrorMsg(model, login.getMsg());
return MB_LOGIN_FTL;
}
UserLoginInOutDTO data = login.getData();
XxlSsoUser xxlUser = new XxlSsoUser();
xxlUser.setUserid(data.getToken());
xxlUser.setUsername(data.getUserName());
xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
xxlUser.setExpireMinute(SsoLoginStore.getRedisExpireMinute());
xxlUser.setExpireFreshTime(System.currentTimeMillis());
// 设置sessionid
String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);
public static String makeSessionId(XxlSsoUser xxlSsoUser){
String sessionId = xxlSsoUser.getUserid().concat("_").concat(xxlSsoUser.getVersion());
return sessionId;
}
官方demo中不支持多端唯一登录,以上也有解决,并且隐藏了userid。
SSO Client应用(Token形式)
浏览器不能访问,可以使用Postman进行测试。
访问地址http://127.0.0.1:8082/xxl-sso-token-sample-springboot/,并带请求头xxl_sso_sessionid:1000_d4a7fbf5f3134f408b806f03968563d8
当浏览器退出登录时,postman请求就显示未登录。
集成到正式项目时,将SSO Server独立建立微服务工程。
在common服务下建立xxlsso-core子工程,放置xxlsso核心代码
public static void login(HttpServletResponse response,
String sessionId,
XxlSsoUser xxlUser,
boolean ifRemember) {
String storeKey = SsoSessionIdHelper.parseStoreKey(sessionId);
if (storeKey == null) {
throw new RuntimeException("parseStoreKey Fail, sessionId:" + sessionId);
}
//存入redis和cookie
SsoLoginStore.put(storeKey, xxlUser);
CookieUtil.set(response, Conf.SSO_SESSIONID, sessionId, ifRemember);
}
首页门户集成SSO Client
pom添加
<dependency>
<groupId>com.ylw</groupId>
<artifactId>taodong-shop-common-xxlsso-core</artifactId>
<version>1.0-RELEASE</version>
</dependency>
application.yml添加
xxl:
sso:
logout:
path: /logout
#可以访问
server: http://hongli.ssoserver.com:8099
在XxlSsoConfig.java中编码如下
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("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private String port;
@Bean
public FilterRegistrationBean xxlSsoFilterRegistration() {
// xxl-sso, redis init
JedisUtil.init(String.format("redis://%s:%s", redisHost, port));
// 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();
}
}
同样的方法对聚合支付门户集成SSO Client。