一 单点登陆系统简介
单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
例如:QQ、rwrew QQ腾讯公司 穿越火线、QQ飞车、QQ华夏、LOL、DNF
用户名就是QQ 密码
定义:同一家公司不同应用使用同一套登陆系统叫做单点登陆系统(单点就是同一套的意思)
单点登陆系统也是要搭建集群
传统部署方式:
二 集成代码实现
2.1 Controller类实现如下代码
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工具类,代码如下
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); //重新写入,将覆盖之前的
}
}
集成完毕