微服務專案中如何整合——XXL-SSO單點登入系統
阿新 • • 發佈:2019-05-28
為什麼需要做單點登陸系統
大型網際網路公司中,公司旗下可能會有多個子系統,每個登陸實現統一管理
多個賬戶資訊統一管理 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認證授權系統)
登陸成功之後跳轉原來地址:
疑問:為什麼在認證授權中心登陸成功之後,會帶一個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