单点登陆案例实现

一 单点登陆系统简介

单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

例如:QQ、rwrew QQ腾讯公司 穿越火线、QQ飞车、QQ华夏、LOL、DNF

用户名就是QQ 密码

定义:同一家公司不同应用使用同一套登陆系统叫做单点登陆系统(单点就是同一套的意思)

单点登陆系统也是要搭建集群

传统部署方式:

二 集成代码实现

2.1 Controller类实现如下代码

java 复制代码
package cn.yty.login.controller;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.codec.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import cn.yty.redis.service.RedisService;
import cn.yty.user.pojo.User;
import cn.yty.user.service.UserService;
import cn.yty.utils.FormatDatetime;
import cn.yty.utils.RequestUtils;
import cn.yty.web.pojo.ReturnState;

@RestController
@RequestMapping("user")
public class UserController {
	
	@Autowired
	private UserService userService;

	@Autowired
	private RedisService redisService;
	
	
	/**
	 * 1  用户登录
	 */
	@GetMapping("login")
	public ReturnState login(String username,String password,
			HttpServletRequest request, HttpServletResponse response,HttpSession session){
		//用户名不能为空
		if (null != username || !"".equals(username)) {
			//密码不能为空
			if (null != password || !"".equals(password)) {
				User user2 = userService.findByUsername(username);
				if (null != user2) 
				{
					//检查密码
					if (encodePassword(password).equals(user2.getPassword())) {
						//将登录信息写入session
						redisService.set(RequestUtils.getToken(request, response),user2.getUsername());
						return new ReturnState("success","登录成功", "200", null);
					}else{
						return new ReturnState("success","用户名或密码错误", "201", null);
					}
				}else{
					return new ReturnState("error","用户名不存在,请注册后登陆!", "302", null);
				}
			}else{
				return new ReturnState("error","密码不能为空!", "401", null);
			}
		}else{
			return new ReturnState("error","用户名不能为空!", "400", null);
		}
	}
	/**
	 * 密码加密
	 */
	private String encodePassword(String password) {
		try {
			//加盐  jdk 各种加密
			MessageDigest instance = MessageDigest.getInstance("MD5");
			//加密产生密文
			byte[] digest = instance.digest(password.getBytes());
			//十六进制再加密一次
			char[] encodeHex = Hex.encode(digest);
			return new String(encodeHex);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}
}

2.2 新建RequestUtils.java工具类,代码如下

java 复制代码
package cn.gog.utils;
import java.util.UUID;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RequestUtils {
	public static String getToken(HttpServletRequest request, HttpServletResponse response){
		//1.Cookie中是否有令牌, 取cookie令牌
		Cookie[] cookies = request.getCookies();
		if(cookies != null && cookies.length > 0){
			for(Cookie cookie : cookies){
				if(cookie.getName().equals("token")){
					//2. 有 直接使用
					return cookie.getValue();
				}
			}
		}
		//3. 没有 生成一个新的令牌
		String token = UUID.randomUUID().toString().replaceAll("-", "");
		//4. 创建cookie并保存令牌
		Cookie cookie = new Cookie("token", token);
		//设置存活时间 -1表示关闭浏览器销毁
		cookie.setMaxAge(-1);
		//设置携带路径(就是在所有项目中都可以获取这个cookie)
		cookie.setPath("/");
		//5. 写回到浏览器
		response.addCookie(cookie);
		//6. 返回新生成的令牌
		return token;
	}


	/**
	 *  清除token
	 */
	 public static void removeToken(HttpServletResponse response){
		Cookie newCookie=new Cookie("token",null); //假如要删除名称为username的Cookie
		newCookie.setMaxAge(0); //立即删除型
		newCookie.setPath("/"); //项目所有目录均有效,这句很关键,否则不敢保证删除
		response.addCookie(newCookie); //重新写入,将覆盖之前的
	 }
}

集成完毕

相关推荐
yxlalm3 小时前
Spring AI+RAG 01-项目背景与技术选型
java·人工智能·spring
程序员清风3 小时前
Java 后端高并发设计:线程池、限流、熔断与降级
java·数据库·oracle
Seoyoneh4 小时前
Agentic Workflow编排架构:云客服从“被动响应”迈向“主动执行”的技术实现
java·开发语言·架构
海南java第二人4 小时前
对外 API 如何保证幂等性?插入数据 / 上传表格场景全方案汇总
java·幂等性
tryxr4 小时前
Chat2Excel 文件服务模块上传文件功能开发
java·项目·oss·easyexcel·文件服务
Tangyuewei4 小时前
Java 写 Agent:模型只是组件
java·开发语言
彧azz5 小时前
Java学习语法篇:变量
java·学习
信誓旦旦的程序猿6 小时前
【量化系统从零构建 #04】存储设计:选型·建库·交易日历
java·人工智能·python·股票数据api·股票数据·股票数据api接口·股票api数据接口
yurenpai(27届找实习中)6 小时前
Java 10 的 var 为什么不能随便用?从订单汇总看懂类型推断与泛型陷阱
java·开发语言·java18
Flynt7 小时前
把公司项目迁到 Spring Boot 4.0:编译通过只是开始
java·spring boot·后端