mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-12-21 10:59:45 +08:00
简化单点登录集成步骤
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
package com.pj.sso;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.ejlchina.okhttps.OkHttps;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.sso.SaSsoUtil;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.sso.SaSsoHandle;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* Sa-Token-SSO Client端 Controller
|
||||
@@ -28,44 +27,21 @@ public class SsoClientController {
|
||||
return str;
|
||||
}
|
||||
|
||||
// SSO-Client端:登录地址
|
||||
@RequestMapping("ssoLogin")
|
||||
public Object ssoLogin(String back, String ticket) {
|
||||
// 如果当前Client端已经登录,则无需访问SSO认证中心,可以直接返回
|
||||
if(StpUtil.isLogin()) {
|
||||
return new ModelAndView("redirect:" + back);
|
||||
}
|
||||
/*
|
||||
* 接下来两种情况:
|
||||
* ticket无值,说明此请求是Client端访问,需要重定向至SSO认证中心
|
||||
* ticket有值,说明此请求从SSO认证中心重定向而来,需要根据ticket进行登录
|
||||
*/
|
||||
if(ticket == null) {
|
||||
String serverAuthUrl = SaSsoUtil.buildServerAuthUrl(SaHolder.getRequest().getUrl(), back);
|
||||
return new ModelAndView("redirect:" + serverAuthUrl);
|
||||
} else {
|
||||
Object loginId = checkTicket(ticket);
|
||||
if(loginId != null ) {
|
||||
// loginId有值,说明ticket有效
|
||||
StpUtil.login(loginId);
|
||||
return new ModelAndView("redirect:" + back);
|
||||
}
|
||||
// 此处向客户端提示ticket无效即可,不要重定向到SSO认证中心,否则容易引起无限重定向
|
||||
return "ticket无效: " + ticket;
|
||||
}
|
||||
// SSO-Client端:处理所有SSO相关请求
|
||||
@RequestMapping("/sso*")
|
||||
public Object ssoRequest() {
|
||||
return SaSsoHandle.clientRequest();
|
||||
}
|
||||
|
||||
// SSO-Client端:校验ticket码,获取对应的账号id
|
||||
private Object checkTicket(String ticket) {
|
||||
// 构建单点注销的回调URL(不需要单点注销时此值可填null )
|
||||
String sloCallback = SaHolder.getRequest().getUrl().replace("/ssoLogin", "/sloCallback");
|
||||
|
||||
// 使用OkHttps请求SSO-Server端,校验ticket
|
||||
String checkUrl = SaSsoUtil.buildCheckTicketUrl(ticket, sloCallback);
|
||||
String loginId = OkHttps.sync(checkUrl).get().getBody().toString();
|
||||
|
||||
// 判断返回值是否为有效账号Id
|
||||
return (SaFoxUtil.isEmpty(loginId) ? null : loginId);
|
||||
|
||||
// 配置SSO相关参数
|
||||
@Autowired
|
||||
private void configSso(SaTokenConfig cfg) {
|
||||
cfg.sso
|
||||
// 配置Http请求处理器
|
||||
.setSendHttp(url -> {
|
||||
return OkHttps.sync(url).get().getBody().toString();
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package com.pj.sso;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.ejlchina.okhttps.OkHttps;
|
||||
import com.pj.util.AjaxJson;
|
||||
|
||||
import cn.dev33.satoken.sso.SaSsoUtil;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* Sa-Token-SSO Client端 单点注销 Controller
|
||||
* @author kong
|
||||
*/
|
||||
@RestController
|
||||
public class SsoClientLogoutController {
|
||||
|
||||
// SSO-Client端:单端注销 (其它Client端会话不受影响)
|
||||
@RequestMapping("logout")
|
||||
public AjaxJson logout() {
|
||||
StpUtil.logout();
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
// SSO-Client端:单点注销 (所有端一起下线)
|
||||
@RequestMapping("ssoLogout")
|
||||
public AjaxJson ssoLogout() {
|
||||
// 如果未登录,则无需注销
|
||||
if(StpUtil.isLogin() == false) {
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
// 调用SSO-Server认证中心API
|
||||
String url = SaSsoUtil.buildSloUrl(StpUtil.getLoginId());
|
||||
String res = OkHttps.sync(url).get().getBody().toString();
|
||||
if(res.equals("ok")) {
|
||||
return AjaxJson.getSuccess("单点注销成功");
|
||||
}
|
||||
return AjaxJson.getError("单点注销失败");
|
||||
}
|
||||
|
||||
// 单点注销的回调
|
||||
@RequestMapping("sloCallback")
|
||||
public String sloCallback(String loginId, String secretkey) {
|
||||
SaSsoUtil.checkSecretkey(secretkey);
|
||||
StpUtil.logoutByLoginId(loginId);
|
||||
return "ok";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package com.pj.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* ajax请求返回Json格式数据的封装
|
||||
*/
|
||||
public class AjaxJson implements Serializable{
|
||||
|
||||
private static final long serialVersionUID = 1L; // 序列化版本号
|
||||
|
||||
public static final int CODE_SUCCESS = 200; // 成功状态码
|
||||
public static final int CODE_ERROR = 500; // 错误状态码
|
||||
public static final int CODE_WARNING = 501; // 警告状态码
|
||||
public static final int CODE_NOT_JUR = 403; // 无权限状态码
|
||||
public static final int CODE_NOT_LOGIN = 401; // 未登录状态码
|
||||
public static final int CODE_INVALID_REQUEST = 400; // 无效请求状态码
|
||||
|
||||
public int code; // 状态码
|
||||
public String msg; // 描述信息
|
||||
public Object data; // 携带对象
|
||||
public Long dataCount; // 数据总数,用于分页
|
||||
|
||||
/**
|
||||
* 返回code
|
||||
* @return
|
||||
*/
|
||||
public int getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给msg赋值,连缀风格
|
||||
*/
|
||||
public AjaxJson setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
return this;
|
||||
}
|
||||
public String getMsg() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给data赋值,连缀风格
|
||||
*/
|
||||
public AjaxJson setData(Object data) {
|
||||
this.data = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将data还原为指定类型并返回
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getData(Class<T> cs) {
|
||||
return (T) data;
|
||||
}
|
||||
|
||||
// ============================ 构建 ==================================
|
||||
|
||||
public AjaxJson(int code, String msg, Object data, Long dataCount) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.data = data;
|
||||
this.dataCount = dataCount;
|
||||
}
|
||||
|
||||
// 返回成功
|
||||
public static AjaxJson getSuccess() {
|
||||
return new AjaxJson(CODE_SUCCESS, "ok", null, null);
|
||||
}
|
||||
public static AjaxJson getSuccess(String msg) {
|
||||
return new AjaxJson(CODE_SUCCESS, msg, null, null);
|
||||
}
|
||||
public static AjaxJson getSuccess(String msg, Object data) {
|
||||
return new AjaxJson(CODE_SUCCESS, msg, data, null);
|
||||
}
|
||||
public static AjaxJson getSuccessData(Object data) {
|
||||
return new AjaxJson(CODE_SUCCESS, "ok", data, null);
|
||||
}
|
||||
public static AjaxJson getSuccessArray(Object... data) {
|
||||
return new AjaxJson(CODE_SUCCESS, "ok", data, null);
|
||||
}
|
||||
|
||||
// 返回失败
|
||||
public static AjaxJson getError() {
|
||||
return new AjaxJson(CODE_ERROR, "error", null, null);
|
||||
}
|
||||
public static AjaxJson getError(String msg) {
|
||||
return new AjaxJson(CODE_ERROR, msg, null, null);
|
||||
}
|
||||
|
||||
// 返回警告
|
||||
public static AjaxJson getWarning() {
|
||||
return new AjaxJson(CODE_ERROR, "warning", null, null);
|
||||
}
|
||||
public static AjaxJson getWarning(String msg) {
|
||||
return new AjaxJson(CODE_WARNING, msg, null, null);
|
||||
}
|
||||
|
||||
// 返回未登录
|
||||
public static AjaxJson getNotLogin() {
|
||||
return new AjaxJson(CODE_NOT_LOGIN, "未登录,请登录后再次访问", null, null);
|
||||
}
|
||||
|
||||
// 返回没有权限的
|
||||
public static AjaxJson getNotJur(String msg) {
|
||||
return new AjaxJson(CODE_NOT_JUR, msg, null, null);
|
||||
}
|
||||
|
||||
// 返回一个自定义状态码的
|
||||
public static AjaxJson get(int code, String msg){
|
||||
return new AjaxJson(code, msg, null, null);
|
||||
}
|
||||
|
||||
// 返回分页和数据的
|
||||
public static AjaxJson getPageData(Long dataCount, Object data){
|
||||
return new AjaxJson(CODE_SUCCESS, "ok", data, dataCount);
|
||||
}
|
||||
|
||||
// 返回,根据受影响行数的(大于0=ok,小于0=error)
|
||||
public static AjaxJson getByLine(int line){
|
||||
if(line > 0){
|
||||
return getSuccess("ok", line);
|
||||
}
|
||||
return getError("error").setData(line);
|
||||
}
|
||||
|
||||
// 返回,根据布尔值来确定最终结果的 (true=ok,false=error)
|
||||
public static AjaxJson getByBoolean(boolean b){
|
||||
return b ? getSuccess("ok") : getError("error");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public String toString() {
|
||||
String data_string = null;
|
||||
if(data == null){
|
||||
|
||||
} else if(data instanceof List){
|
||||
data_string = "List(length=" + ((List)data).size() + ")";
|
||||
} else {
|
||||
data_string = data.toString();
|
||||
}
|
||||
return "{"
|
||||
+ "\"code\": " + this.getCode()
|
||||
+ ", \"msg\": \"" + this.getMsg() + "\""
|
||||
+ ", \"data\": " + data_string
|
||||
+ ", \"dataCount\": " + dataCount
|
||||
+ "}";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -14,11 +14,15 @@ sa-token:
|
||||
sso:
|
||||
# SSO-Server端 单点登录地址
|
||||
auth-url: http://sa-sso-server.com:9000/ssoAuth
|
||||
# 使用Http请求校验ticket
|
||||
is-http: true
|
||||
# SSO-Server端 ticket校验地址
|
||||
check-ticket-url: http://sa-sso-server.com:9000/checkTicket
|
||||
# SSO-Server端 单点注销地址
|
||||
check-ticket-url: http://sa-sso-server.com:9000/ssoCheckTicket
|
||||
# 打开单点注销功能
|
||||
is-slo: true
|
||||
# 单点注销地址
|
||||
slo-url: http://sa-sso-server.com:9000/ssoLogout
|
||||
# 接口调用秘钥(用于SSO模式三的单点注销功能)
|
||||
# 接口调用秘钥
|
||||
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
|
||||
|
||||
spring:
|
||||
|
||||
Reference in New Issue
Block a user