您的位置:首页 > 其它

微服务项目中如何集成——XXL-SSO单点登录系统

2019-05-28 07:13 3659 查看

为什么需要做单点登陆系统

大型互联网公司中,公司旗下可能会有多个子系统,每个登陆实现统一管理
多个账户信息统一管理 SSO单点登陆认证授权系统

总体设计架构图

单点登陆系统实现思路

单点登陆系统框架官方网址

https://github.com/xuxueli/xxl-sso  xxl-sso

http://www.xuxueli.com/xxl-sso/#/ xxl-sso官方文档

思考需要修改XXL-SSO框架的几点

1.	修改XXL-SSO认证服务授权页面样式
2.	修改XXL-SSO认证服务数据库账号密码

http://xxlssoclient1.com:8084/xxl-sso-web-sample-springboot/

http://xxlssoclient2.com:8085/xxl-sso-web-sample-springboot/

客户端访问http://xxlssoclient1.com:8084重定向http://xxlssoserver.com:8080(SSO认证授权系统)

登陆成功之后跳转原来地址:

http://xxlssoclient1.com:8084/xxl-sso-web-sample-springboot/?xxl_sso_sessionid=1000_1db53a90152140c6a8421c83546f75ab

疑问:为什么在认证授权中心登陆成功之后,会带一个xxl_sso_sessionid参数。
疑问:为什么ssoClient需要集成redis
源码分析:

思考问题:
访问客户端的时候,如何自动重定向到认证授权中心的?

过滤器请求,如果没有获取到用户的会话信息的话,自动重定向跳转到认证授权中心

重点断点调试 核心依赖Jar中 XxlSsoWebFilter类
Client原理分析:

1.	先从Cookie中获取当前CookieId
2.	如果用户没有登陆的情况下,重定向到认证授权中心

http://xxlssoserver.com:8080/xxl-sso-server/login?redirect_url=http://xxlssoclient1.com:8084/xxl-sso-web-sample-springboot/
为什么redirect_url地址
在认证授权中心登陆成功之后,返回原来地址 (回调地址)

3.	认证授权登陆成功之后,在认证授权域名下存放对应的cookie信息
4. 认证授权系统回调到子系统中传递xxl_sso_sessionid
http://xxlssoclient1.com:8084/xxl-sso-web-sample-springboot/?xxl_sso_sessionid=1000_4529db8531d54e23856e44002ace6cbb

4.	回调到子系统的时候,进XxlSsoWebFilter拦截 获取xxl_sso_sessionid 信息
5.	子系统使用xxl_sso_sessionid从redis查询认证授权系统登陆的用户信息,将用户信息在子系统域名下存放对应的用户Cookie信息
这样的 可以保证 认证授权系统和子系统双方Cookie信息同步

项目如何集成XXL-SSO项目

A.	认证授权中心xxl-sso-server
1.	修改登陆数据库验证
2.	修改页面静态资源
B.	SSOClient端整合

创建认证授权中心meite-shop-basics-xxl-sso-server

<!-- freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- sso core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-sso-core</artifactId>
<version>1.1.1-SNAPSHOT</version>
</dependency>
<!-- springcloud feign组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.xuyu</groupId>
<artifactId>xuyu-shop-service-api-member</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.xuyu</groupId>
<artifactId>xuyu-shop-common-web-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

改造登陆代码

userLoginInpDTO.setMobile(username);
userLoginInpDTO.setPassword(password);
userLoginInpDTO.setLoginType(Constants.MEMBER_LOGIN_TYPE_PC);
String info = webBrowserInfo(request);
userLoginInpDTO.setDeviceInfor(info);
BaseResponse<UserOutDTO> ssoLogin = memberServiceFeign.ssoLogin(userLoginInpDTO);
if (!isSuccess(ssoLogin)) {
redirectAttributes.addAttribute("errorMsg", ssoLogin.getMsg());
redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
return "redirect:/login";
}
UserOutDTO data = ssoLogin.getData();
if (data == null) {
redirectAttributes.addAttribute("errorMsg", "用户信息数据为空!");
redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
return "redirect:/login";
}

登陆接口

@Override
public BaseResponse<UserOutDTO> ssoLogin(@RequestBody UserLoginInpDTO userLoginInpDTO) {
// 1.验证参数
String mobile = userLoginInpDTO.getMobile();
if (StringUtils.isEmpty(mobile)) {
return setResultError("手机号码不能为空!");
}
String password = userLoginInpDTO.getPassword();
if (StringUtils.isEmpty(password)) {
return setResultError("密码不能为空!");
}
// 判断登陆类型
String loginType = userLoginInpDTO.getLoginType();
if (StringUtils.isEmpty(loginType)) {
return setResultError("登陆类型不能为空!");
}
// 目的是限制范围
if (!(loginType.equals(Constants.MEMBER_LOGIN_TYPE_ANDROID) || loginType.equals(Constants.MEMBER_LOGIN_TYPE_IOS)
|| loginType.equals(Constants.MEMBER_LOGIN_TYPE_PC))) {
return setResultError("登陆类型出现错误!");
}

// 设备信息
String deviceInfor = userLoginInpDTO.getDeviceInfor();
if (StringUtils.isEmpty(deviceInfor)) {
return setResultError("设备信息不能为空!");
}
// 2.对登陆密码实现加密
String newPassWord = MD5Util.MD5(password);
// 3.使用手机号码+密码查询数据库 ,判断用户是否存在
UserDo userDo = userMapper.login(mobile, newPassWord);
if (userDo == null) {
return setResultError("用户名称或者密码错误!");
}
return setResultSuccess(MeiteBeanUtils.doToDto(userDo, UserOutDTO.class));
}
/**
* SSO认证系统登陆接口
*
* @param userLoginInpDTO
* @return
*/
@PostMapping("/ssoLogin")
public BaseResponse<UserOutDTO> ssoLogin(@RequestBody UserLoginInpDTO userLoginInpDTO);

shop-portal项目集成

application.yml

#### 整合freemarker
spring:
freemarker:
cache: false
charset: UTF-8
check-template-location: true
content-type: text/html
expose-request-attributes: true
expose-session-attributes: true
request-context-attribute: request
suffix: .ftl
template-loader-path:
- classpath:/templates
application:
name: app-xuyu-portal-pay
###服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
server:
port: 8050
redis:
hostname: 127.0.0.1
port: 6379
password: 123456

xxl-sso:
excluded:
paths:
xxl:
sso:
server: http://xxlssoserver.com:8080/xxl-sso-server
logout:
path: /logout
redis:
address: redis://127.0.0.1:6379

XxlSsoConfig

@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();
}
}

在线properties转yml方式

https://www.bejson.com/devtools/properties2yaml/

host文件配置域名

127.0.0.1 pay.xuyu.com:8050 支付项目
127.0.0.1 www.xuyu.com 门户网站

单点登陆系统设计思想都是一样

联合登陆都会遵循oatuh2.0协议

思考:我们在项目中,如何集成xxl-sso框架?

肯定是修改xxl-sso框架?应该修改那些地方?
1.	认证授权中心
需要介入微服务基础设施
修改登陆验证接口(调用会员数据库验证)
需要修改登陆界面
2.	SSOClient集成
集成XxlSsoConfig使用XxlSsoWebFilter(注意排除请求)

portal-web 会员登陆、注册 商品搜索、下单
pay-web 单独 聚合支付  银联 支付宝 微信支付

portal-web pay-web 需要实现SSO单点登陆

 XXL-SSO退出源码分析

http://www.xuxueli.com/xxl-sso/#/?id=%E9%85%8D%E7%BD%AE%E8%AF%B4%E6%98%8E-1

XXL-SSO认证授权中心如何实现高可用

使用Nginx实现xxl-sso-server认集群和故障转移

upstream  backServer{
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
listen       80;
server_name  xxlssoserver.com;
location / {
proxy_pass http://backServer;
###nginx与上游服务器(真实访问的服务器)超时时间 后端服务器连接的超时时间_发起握手等候响应超时时间
proxy_connect_timeout 1s;
###nginx发送给上游服务器(真实访问的服务器)超时时间
proxy_send_timeout 1s;
### nginx接受上游服务器(真实访问的服务器)超时时间
proxy_read_timeout 1s;
index  index.html index.htm;
}
}

XXL-SSOToken认证

1.如何保证SSO-Server高可用的问题
2.可以考虑SSO-Servet集群问题

思考:SSOClient实现注销,URL地址如何拼接
1.SSO基于Cookie 形式 、Token形式
2.SSO基于Token形式的实现  普通登陆一模一样的路程

基于令牌形式实现SSO

1.	调用认证授权中心接口登陆返回用户令牌信息
2.	SSOClient项目需要实现单点登陆的话,在调用SSOClient接口的时候请求头中传递Token信息
3.	sessionId 相当于Token

 

(adsbygoogle = window.adsbygoogle || []).push({});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  xxl-sso