springboot实现用户统一认证管理(单点登录)

Posted 穆雄雄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot实现用户统一认证管理(单点登录)相关的知识,希望对你有一定的参考价值。

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂

前言

现在是:2022年5月25日13:44:16

最近和模拟登录杠上了,这不,又来了个需求,还是以这个技术点入手的。
需求大概是这样的:为了统一管理系统的用户,上游平台做了个统一认证平台,所有用户进入子系统只有一个入口,即:上游平台登录入口,新用户也是上游平台进行添加;子系统的用户登录和注册模块都屏蔽掉。

设计技能点

  1. 前端:Vue
  2. 后端:springboot (bladex框架)
  3. 数据库:mysql 5.7及以上

实现思路

  1. 上游平台通过回调接口,将用户和组织机构同步至子系统
  2. 上游平台通过url在地址栏中挂sessionid的方式访问子系统的登录页面
  3. 子系统检地址栏中是否有sessionid,如果有,则拿着sessionid去上游系统获取用户信息,然后在子系统中拿着用户信息自动登录
  4. 如果地址栏中没有sessionid,则需要带着子系统的登录地址,重定向至上游平台(上游平台怎么处理的,我就不知道了,我猜测,如果用户未在上游平台登录,则不带sessionid来的子系统,如果登录了则会带着过来。所以重定向到上游平台时,应该是让用户重新进行登录的)
  5. 当用户点击退出时,清除子系统的用户登录状态的同时还需要清除上游系统,且重定向至上游平台的登录页面

代码实现

回调接口实现了两个功能:

  • 同步组织机构
  • 同步用户信息

为了后期维护方便,前后端所有调用外部的地址,从接口中获取数据等均单独提取出来了,这样也能更好的实现复用。

  1. 统一接口管理SsoLoginConstant
	package org.springblade.modules.system.util;

	/**
	* @Description: TODO
	* @author: 穆雄雄
	* @date: 2022/5/17 下午 2:40
	 * 放一些公共的常量
	* @Return:
	*/
	public interface SsoLoginConstant 

		/**
		 * 统一认证平台的地址
		 */
		public final static String SSO_URL = "http://************";


		/**
		 * 登录鉴权
		 */

		public final static  String CHECKLOGIN_URL =SSO_URL+ "/check_login";

		/**
		 * 查询平台用户信息
		 */
		public final static  String QUERYUSER_URL =SSO_URL+ "/get_user";

		/**
		 * 查询平台组织机构信息
		 */
		public final static String QUERYDEPARTMENT_URL =SSO_URL+ "/get_department";

		/**
		 * 退出系统
		 */
		public final static String APILOGOUT_URL =SSO_URL+ "/api_logout";


	

  1. 公用Service层接口:

	package org.springblade.modules.system.service;

	import org.springblade.core.tool.api.R;
	import org.springframework.web.bind.annotation.RequestBody;

	/**
	 * @author: muxiongxiong
	 * @date: 2022年05月21日 上午 8:41
	 * 公众号:雄雄的小课堂
	 * 博客:https://blog.csdn.net/qq_34137397
	 * 个人站:http://www.穆雄雄.com
	 * 个人站:http://www.muxiongxiong.cn
	 * @Description: 类的描述:单点登录业务层接口
	 */
	public interface ISsoLoginService 

		/**
		* @Description: 登录鉴权
		* @author: 穆雄雄
		* @date: 2022/5/21 上午 8:54
		No such property: code for class: Script1
		* @Return:
		*/
		String checkLogin(String ssoSessionKey);

		/**
		 * @Description: 查询平台用户信息
		 * @author: 穆雄雄
		 * @date: 2022/5/21 上午 8:42
		 * 查询平台用户信息
		 * @Return:
		 */
		String getUser(String projectKey);

		/**
		* @Description: 查询平台组织机构信息
		* @author: 穆雄雄
		* @date: 2022/5/21 上午 8:50
		* 查询平台用户信息
		* @Return: java.lang.String
		*/
		String getDepartment(String projectKey);

		/**
		* @Description: 上传平台用户信息
		* @author: 穆雄雄
		* @date: 2022/5/21 上午 9:24
		* @Return: java.lang.String
		*/
		R pullUserInfo(@RequestBody String val);

		/**
		 * @Description: 退出
		 * @author: 穆雄雄
		 * @date: 2022年5月25日15:34:58
		No such property: code for class: Script1
		 * @Return:
		 */
		String apiLogout(String ssoSessionKey);

	


  1. Service层实现类:
	package org.springblade.modules.system.service.impl;

	import cn.hutool.http.HttpUtil;
	import com.alibaba.fastjson.JSONArray;
	import com.alibaba.fastjson.JSONObject;
	import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
	import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
	import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
	import org.apache.commons.lang.StringUtils;
	import org.springblade.core.tool.api.R;
	import org.springblade.modules.system.entity.Dept;
	import org.springblade.modules.system.entity.User;
	import org.springblade.modules.system.entity.UserService;
	import org.springblade.modules.system.service.IDeptService;
	import org.springblade.modules.system.service.ISsoLoginService;
	import org.springblade.modules.system.service.IUserService;
	import org.springblade.modules.system.util.SsoLoginConstant;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.stereotype.Service;

	import java.util.HashMap;
	import java.util.Map;

	/**
	 * @author: muxiongxiong
	 * @date: 2022年05月21日 上午 8:51
	 * 公众号:雄雄的小课堂
	 * 博客:https://blog.csdn.net/qq_34137397
	 * 个人站:http://www.穆雄雄.com
	 * 个人站:http://www.muxiongxiong.cn
	 * @Description: 类的描述
	 */
	@Service
	public class SsoLoginServiceImpl implements ISsoLoginService 

		@Autowired
		private IUserService userService;

		@Autowired
		private IDeptService deptService;


		/**
		 * 登录鉴权
		 */
		@Override
		public String checkLogin(String ssoSessionKey) 
			JSONObject jsonObjectResult = new JSONObject();
			//请求接口地址
			String url = SsoLoginConstant.CHECKLOGIN_URL;
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("ssoSessionKey", ssoSessionKey);
			try 
				String body = HttpUtil.createPost(url).form(paramMap).execute().body();
				if (StringUtils.isBlank(body)) 
					jsonObjectResult.put("code", 500);
					jsonObjectResult.put("msg", "请求失败");
					jsonObjectResult.put("data", "");
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
				JSONObject obj = JSONObject.parseObject(body);
				if (obj == null) 
					jsonObjectResult.put("code", 500);
					jsonObjectResult.put("msg", "请求失败");
					jsonObjectResult.put("data", "");
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
				String code = obj.get("code").toString();
				if ("200".equals(code)) 
					jsonObjectResult.put("code", 200);
					jsonObjectResult.put("msg", "请求成功");
					jsonObjectResult.put("data", obj.get("data"));
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				else
					jsonObjectResult.put("code", 500);
					jsonObjectResult.put("msg", "请求失败");
					jsonObjectResult.put("data", "");
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
			 catch (Exception e) 
				e.printStackTrace();
			
			return jsonObjectResult.toJSONString();
		

		/**
		 * 获取平台用户
		 */
		@Override
		public String getUser(String projectKey) 
			JSONObject jsonObjectResult = new JSONObject();
			//请求接口地址
			String url = SsoLoginConstant.QUERYUSER_URL;
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("projectKey", projectKey);
			try 
				String body = HttpUtil.createGet(url).form(paramMap).execute().body();
				if (StringUtils.isBlank(body)) 
					jsonObjectResult.put("code", 500);
					jsonObjectResult.put("msg", "请求失败");
					jsonObjectResult.put("data", "");
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
				JSONObject obj = JSONObject.parseObject(body);
				if (obj == null) 
					jsonObjectResult.put("code", 500);
					jsonObjectResult.put("msg", "请求失败");
					jsonObjectResult.put("data", "");
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
				String code = obj.get("code").toString();
				if ("200".equals(code)) 
					jsonObjectResult.put("code", 200);
					jsonObjectResult.put("msg", "请求成功");
					jsonObjectResult.put("data", obj.get("data"));
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
			 catch (Exception e) 
				e.printStackTrace();
			
			return jsonObjectResult.toJSONString();
		

		/**
		 * 获取组织机构
		 */
		@Override
		public String getDepartment(String projectKey) 
			JSONObject jsonObjectResult = new JSONObject();
			//请求接口地址
			String url = SsoLoginConstant.QUERYDEPARTMENT_URL;
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("projectKey", projectKey);
			try 
				String body = HttpUtil.createGet(url).form(paramMap).execute().body();
				if (StringUtils.isBlank(body)) 
					jsonObjectResult.put("code", 500);
					jsonObjectResult.put("msg", "请求失败");
					jsonObjectResult.put("data", "");
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
				JSONObject obj = JSONObject.parseObject(body);
				if (obj == null) 
					jsonObjectResult.put("code", 500);
					jsonObjectResult.put("msg", "请求失败");
					jsonObjectResult.put("data", "");
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
				String code = obj.get("code").toString();
				if ("200".equals(code)) 
					jsonObjectResult.put("code", 200);
					jsonObjectResult.put("msg", "请求成功");
					jsonObjectResult.put("data", obj.get("data"));
					jsonObjectResult.put("status", false);
					return jsonObjectResult.toJSONString();
				
			 catch (Exception e) 
				e.printStackTrace();
			
			return jsonObjectResult.toJSONString();
		

		/**
		 * 上传平台用户信息
		 * @param val
		 * @return
		 */
		@Override
		public R pullUserInfo(String val) 
			//转换成集合类型
			JSONArray userListArray = JSONArray.parseArray(val);
			boolean flag = false;
			for (Object o : userListArray) 
				JSONObject jsonObject = (JSONObject) o;
				User user = new User();
				//add表示添加
				//update表示更新
				//delete表示删除
				String operate = jsonObject.getString("operate");
				//固定标识
				String type = jsonObject.getString("type");
				JSONObject dataObject = jsonObject.getJSONObject("data");
				if (type.equals("sso_user")) 
					Long id = dataObject.getLong("id");
					//用户账号
					String account = dataObject.getString("account");
					//用户名称
					String name = dataObject.getString("name");
					//所属部门
					String departmentId = dataObject.getString("departmentId");
					//手机号
					String mobile = dataObject.getString("mobile");
					//用户角色,1表示管理者,2表示使用者
					String isManager = dataObject.getString("isManager");
					//应用编号
					String project = dataObject.getString("project");

					//添加用户
					user.setId(id);
					user.setPhone(mobile);
					user.setTenantId("000000");
					user.setCode("");
					if(isManager.equals("1"))
						//管理员
						user.setRoleId("1529303109787967490");
					else if(isManager.equals("2"))
						//一般用户
						user.setRoleId("1529302965017370625");
					else
						//会员(这个地方不会执行到,只要isManager不等于null)
						user.setRoleId("1355058724514836481");
					
					user.setUserType(Integer.parseInt(isManager));
					user.setAccount(account);
					//密码是123456
					user.setPassword("10470c3b4b1fed12c3baac014be15fac67c6e815");
					user.setName(name);
					user.setRealName(name);

					user.setDeptId(departmentId);
					user.setStatus(SpringBoot实现用户统一管理与单点登陆

IdentityServer4实现单点登录统一认证

SSO统一身份认证——CAS Client客户端创建(九)

权限认证系统, 实现类似单点登录的功能

springboot实现用户统一认证管理

SSO统一身份认证——CAS Server6.3.x设定退出方式(十二)