单点登录-待调试

This commit is contained in:
liyawei
2022-03-18 18:31:18 +08:00
parent d6c3dc4a29
commit 58dff6ffed
4 changed files with 265 additions and 0 deletions
@@ -134,6 +134,8 @@ public class ShiroConfig {
//性能监控 TODO 存在安全漏洞泄露TOEKN(durid连接池也有)
filterChainDefinitionMap.put("/actuator/**", "anon");
filterChainDefinitionMap.put("/opensso/**", "anon"); //单点登录
// 添加自己的过滤器并且取名为jwt
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
//如果cloudServer为空 则说明是单体 需要加载跨域配置
@@ -0,0 +1,56 @@
package com.jero.modules.opensso;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
/**
* @Description
* @Author liyawei
* @Create 2021/8/17
*/
public class URLRequestResultUtil {
public static String getProxyRequestResult(String url) {
StringBuffer requestResult = new StringBuffer();
BufferedReader in = null;
try {
System.out.println(url);
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream(), "utf-8"));
String line;
while ((line = in.readLine()) != null) {
requestResult.append(line);
}
}
// 使用finally块来关闭输入流
catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return requestResult.toString();
}
}
@@ -0,0 +1,205 @@
package com.jero.modules.opensso.controller;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jero.common.api.vo.Result;
import com.jero.common.aspect.annotation.AutoLog;
import com.jero.common.constant.CommonConstant;
import com.jero.common.system.api.ISysBaseAPI;
import com.jero.common.system.util.JwtUtil;
import com.jero.common.system.vo.LoginUser;
import com.jero.common.util.RedisUtil;
import com.jero.common.util.oConvertUtils;
import com.jero.modules.base.service.BaseCommonService;
import com.jero.modules.opensso.URLRequestResultUtil;
import com.jero.modules.system.entity.SysDepart;
import com.jero.modules.system.entity.SysUser;
import com.jero.modules.system.service.ISysDepartService;
import com.jero.modules.system.service.ISysDictService;
import com.jero.modules.system.service.ISysLogService;
import com.jero.modules.system.service.ISysUserService;
import com.jero.modules.system.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: liyawei
* @Description:
* @Date: Created in 11:19 2022/3/17
*/
@RestController
@RequestMapping("/opensso")
@Api(tags="单点登录")
@Slf4j
public class SSOLoginController {
@Autowired
private ISysUserService sysUserService;
@Autowired
private ISysBaseAPI sysBaseAPI;
@Autowired
private ISysLogService logService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private ISysDepartService sysDepartService;
@Autowired
private ISysDictService sysDictService;
@Resource
private BaseCommonService baseCommonService;
@Autowired
private RestTemplate restTemplate;
private static final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
//密码登录错误的次数前缀
public static final String RETRY_LOGIN_PREFIX = "login:retryLoginCount_";
//密码登录错误的最大限制次数
public static final int RETRY_LOGIN_MAX_COUNT = 5;
private String accessTokenUrl = "https://signin-test.nio.com/oauth2/accessToken";
private String profileUrl = "https://signin-test.nio.com/oauth2/profile";
private String clientId = "100679";
private String clientSecret = "CDf2D9404C6ac1B0f7c3e3845ae0282a";
@Value("${opensso.redirectUri}")
private String redirectUri;
@AutoLog(value = "跳转至认证中心")
@ApiOperation(value = "跳转至认证中心", notes = "跳转至认证中心")
@GetMapping(value = "/ssoAuth")
public void ssoAuth(HttpServletRequest request, HttpServletResponse response){
String callbackUri = "http%3A%2F%2F139.9.235.66%3A8008%2Fjero-boot%2Fopensso%2Fcallback";
String authUrl = "https://signin-test.nio.com/oauth2/authorize" +"?client_id=" + clientId
+ "&redirect_uri=" + redirectUri + "&response_type=code";
try {
response.sendRedirect(authUrl);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
//https://signin-test.nio.com/oauth2/authorize?client_id=100679&redirect_uri=http%3A%2F%2F139.9.235.66%3A8008%2Fjero-boot%2Fopensso%2Fcallback&response_type=code
@AutoLog(value = "单点登录回调")
@ApiOperation(value = "单点登录回调", notes = "单点登录回调")
@GetMapping(value = "/callback")
public Result<?> callback(@RequestParam(value = "code", required = false) String code,
HttpServletRequest request, HttpServletResponse response) throws IOException {
Result<JSONObject> result = new Result<JSONObject>();
// 获取access_token
String getAccessTokenUrl = accessTokenUrl + "?client_id=" + clientId + "&client_secret="
+ clientSecret + "&redirect_uri=" + redirectUri + "&code=" + URLEncoder.encode(code, "utf-8");
log.info("access_token_url:" + getAccessTokenUrl);
Map<String, String> headerMapToken = new HashMap<>();
headerMapToken.put("Content-Type", "text/html;charset=utf-8");
// String accessTokenResult = HttpRequestUtil.getResponseOfGET(accessTokenUrl, headerMapToken);
String accessTokenResult = URLRequestResultUtil.getProxyRequestResult(accessTokenUrl);
log.info("获取access_token返回结果:" + accessTokenResult);
// 返回结果:access_token=2.0N6OFCARTH7MRCVPSENQONSA67WGHV4FDR25TSHFCCXI6FA3NRVAA----&expires=602405
if(StringUtils.isEmpty(accessTokenResult) || !accessTokenResult.contains("access_token")){
return Result.error("【单点登录】获取access_token失败");
}
int start = accessTokenResult.indexOf("=");
int end = accessTokenResult.indexOf("&");
String accessToken = accessTokenResult.substring(start+1, end);
//https://signin-test.nio.com/oauth2/profile?access_token=2.0N6OFCARTH7MRCVPSENQONSA67WGHV4FDR25TSHFCCXI6FA3NRVAA----
//获取登录用户
String getProfileUrl = profileUrl + "?access_token=" + URLEncoder.encode(accessToken, "utf-8");
log.info("profile_url:" + getProfileUrl);
Map<String, String> headerMapProfile = new HashMap<>();
headerMapProfile.put("Content-Type", "application/json; charset=utf-8");
// String profileResult = HttpRequestUtil.getResponseOfGET(getProfileUrl, headerMapProfile);
String profileResult = URLRequestResultUtil.getProxyRequestResult(getProfileUrl);
log.info("获取profile返回结果:" + profileResult);
// 返回结果:{ id: "xuetao.li3.o", attributes: [{workNo: "CW19057"},{account_id: ""},{user_name: "xuetao.li3.o"},{email: "xuetao.li3.o@nio.com"}]}
JSONObject userThirdIdJson = JSONObject.parseObject(profileResult);
if(ObjectUtil.isEmpty(userThirdIdJson) || !userThirdIdJson.containsKey("id")){
return Result.error("【单点登录】获取用户profile失败");
}
String userThirdId = userThirdIdJson.getString("id");
String username = userThirdId;
//1. 校验用户是否有效
//update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getUsername,username);
SysUser sysUser = sysUserService.getOne(queryWrapper);
//update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false
result = sysUserService.checkUserIsEffective(sysUser);
if(!result.isSuccess()) {
return result;
}
//登录成功,清除错误登录次数
redisUtil.del(RETRY_LOGIN_PREFIX + username);
//用户登录信息
userInfo(sysUser, result);
//update-begin--Author:wangshuai Date:20200714 for:登录日志没有记录人员
LoginUser loginUser = new LoginUser();
BeanUtils.copyProperties(sysUser, loginUser);
baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
//update-end--Author:wangshuai Date:20200714 for:登录日志没有记录人员
return result;
}
/**
* 用户信息
*
* @param sysUser
* @param result
* @return
*/
private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result) {
String syspassword = sysUser.getPassword();
String username = sysUser.getUsername();
// 生成token
String token = JwtUtil.sign(username, syspassword);
// 设置token缓存有效时间
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
// 获取用户部门信息
JSONObject obj = new JSONObject();
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
obj.put("departs", departs);
if (departs == null || departs.size() == 0) {
obj.put("multi_depart", 0);
} else if (departs.size() == 1) {
sysUserService.updateUserDepart(username, departs.get(0).getOrgCode());
obj.put("multi_depart", 1);
} else {
//查询当前是否有登录部门
// update-begin--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
SysUser sysUserById = sysUserService.getById(sysUser.getId());
if(oConvertUtils.isEmpty(sysUserById.getOrgCode())){
sysUserService.updateUserDepart(username, departs.get(0).getOrgCode());
}
// update-end--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
obj.put("multi_depart", 2);
}
obj.put("token", token);
obj.put("userInfo", sysUser);
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
result.setResult(obj);
result.success("登录成功");
return result;
}
}
@@ -376,3 +376,5 @@ Feishu:
batchSendMessageUrl: https://open.feishu.cn/open-apis/message/v4/batch_send/
local-tool:
uri: http://139.9.235.66:9022
opensso:
redirectUri: http%3A%2F%2F139.9.235.66%3A8008%2Fjero-boot%2Fopensso%2Fcallback