SSO单点登录核心原理

简介: SSO单点登录核心原理

登录接口

@RequestMapping("/doLogin")
  @ResponseBody
  public SysResult login(User user,HttpServletResponse response) {
    //1.校验数据是否正确.获取密钥
    String ticket = userService.findUserByUP(user);
    if(StringUtils.isEmpty(ticket)) {
      return SysResult.fail();
    }
    //2.如果程序执行到这里.表示密钥有值.写入cookie
    Cookie cookie = new Cookie("JT_TICKET", ticket);
    cookie.setMaxAge(7 * 24 * 3600);
    cookie.setPath("/");
    //设定cookie的共享! 这样当访问order.jt.com或者cart.jt.com的时候都会带上这个Cookie
    cookie.setDomain("jt.com");
    //将cookie写入客户端
    response.addCookie(cookie);
    return SysResult.success();
  }

其中userService.findUserByUP(user);方法是:

@Override
  public String findUserByUP(User user) {
    String ticket = null;
    //为了与数据库数据一致,需要将密码加密
    String md5Pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
    user.setPassword(md5Pass);
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>(user);
    //根据用户名和密码校验数据
    User userDB = userMapper.selectOne(queryWrapper);
    if(userDB !=null) {
      //将数据库数据转化为json保存到redis中
      String uuid = UUID.randomUUID().toString();
      ticket = DigestUtils.md5DigestAsHex(uuid.getBytes());
      //进行脱敏处理   100xxx0311  
      userDB.setPassword("123456你信吗??");
      String userJSON = 
          ObjectMapperUtil.toJSON(userDB);
      jedisCluster.setex(ticket,7*24*3600, userJSON);
    }
    return ticket;
  }

拦截器

当访问xxx.jt.com的时候会带上登录返回的Cookie 拦截器中配置了校验Cookie的方法,具体实现如下:

@Component //交给spring容器管理
public class UserInterceptor implements HandlerInterceptor{
  private static final String TICKET = "JT_TICKET";
  
  @Autowired
  private JedisCluster jedisCluster;
  /**
   * 实现用户权限认证
   *  1.用户不登陆,不允许访问涉密操作.重定向到
   *  用户登录页面.
   *  2.如果用户登录,则请求予以放行.
   *  
   * 方法说明:
   *  1.boolean  
   *    true: 放行
   *    false: 拦截 配合重定向使用
   * 实现步骤:
   *  1.获取用户的Cookie信息. 获取密钥
   *  2.从redis中获取数据.   
   */
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    Cookie[] cookies = request.getCookies();
    String ticket = null;
    //判断cookie是有效的.
    if(cookies.length > 0 ) {
      for (Cookie cookie : cookies) {
        if(TICKET.equals(cookie.getName())) {
          ticket = cookie.getValue();
          break;
        }
      }
    }
    
    if(!StringUtils.isEmpty(ticket)) {
      //校验redis中是否有数据
      String userJSON = jedisCluster.get(ticket);
      if(!StringUtils.isEmpty(userJSON)) {
        //实现用户信息的动态获取
        User user = ObjectMapperUtil.toObject(userJSON,User.class);
        request.setAttribute("JT_USER", user);
        UserThreadLocalUtil.set(user);
        return true;
      }
    }
    
    //如果用户没有登录需要重定向到登录页面
    response.sendRedirect("/user/login.html");
    return false; 
  }
  
  
  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      throws Exception {
    
    //防止内存溢出
    UserThreadLocalUtil.remove();
  }
  
}

其中的UserThreadLocalUtil具体为:

public class UserThreadLocalUtil {
  
  private static 
  ThreadLocal<User> userThread = 
          new ThreadLocal<>();
  
  public static void set(User user) {
    
    userThread.set(user);
  }
  
  public static User get() {
    
    return userThread.get();
  }
  
  public static void remove() {
    
    //防止内存泄漏
    userThread.remove();
  }
}

拦截器配置拦截路径

@Configuration
public class MvcConfigurer implements WebMvcConfigurer{
  
  @Autowired
  private UserInterceptor userInterceptor;
  
  /**
   * 拦截器路径:
   *  /cart/*  拦截url请求中/cart/xxxx 下的一级路径
   *  /cart/** 拦截cart下的所有路径
   */
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    
    registry.addInterceptor(userInterceptor).addPathPatterns("/cart/**","/order/**");
  }
  
}

退出登录

/**
   * 实现用户登出操作.
   *  0.获取cookie数据
   *  1.删除redis  key~~~ticket
   *  2.删除cookie
   * @return
   */
  @RequestMapping("/logout")
  public String logout(HttpServletRequest request,HttpServletResponse response) {
    Cookie[] cookies = request.getCookies();
    String ticket = null;
    //判断cookie是有效的.
    if(cookies.length > 0 ) {
      for (Cookie cookie : cookies) {
        if(TICKET.equals(cookie.getName())) {
          ticket = cookie.getValue();
          break;
        }
      }
    }
    
    if(!StringUtils.isEmpty(ticket)) {
      //如果数据不为null,则删除数据
      jedisCluster.del(ticket);
      Cookie cookie = new Cookie(TICKET, "");
      cookie.setMaxAge(0); //立即删除
      cookie.setPath("/");
      cookie.setDomain("jt.com");
      response.addCookie(cookie);
    }
    
    //重定向到系统首页
    return "redirect:/"; 
  }

总结

用户登录后,将返回的凭证塞入Cookie返回给浏览器,并且存一份到Redis(凭证作为key,对应的用户信息为value,并设置对应的过期时间),当用户访问其他同后缀的域名时 比如order.jt.com或者cart.jt.com时,浏览器会自动带上之前的Cookie,拦截器中校验Cookie中存的凭证在Redis中查询是否有该用户,有的话放行,没有重定向到登录页面.

目录
相关文章
|
存储 安全 Java
OAuth2实现单点登录SSO完整教程,其实不难!(上)
OAuth2实现单点登录SSO完整教程,其实不难!
4664 1
OAuth2实现单点登录SSO完整教程,其实不难!(上)
|
存储 NoSQL 中间件
单点登录的原理、实现、以及技术方案比较详解
本文详细介绍单点登录(SSO)的定义、原理、实现细节,探讨其在大型网站中的应用,帮助读者理解如何通过分布式Session实现高效的用户认证与授权。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
单点登录的原理、实现、以及技术方案比较详解
|
开发框架 算法 安全
如何使用单点登录(SSO)提高账号安全性和用户体验?
单点登录(SSO)是作为此问题的解决方案而引入的,它是一种身份验证方案,允许用户使用一组凭据登录多个应用程序。因此,用户不必在每次需要访问其应用程序时都输入其凭据,如果跨应用程序和平台启用了 SSO,则用户对一个应用程序或平台的成功身份验证将用于访问其他连接的应用程序。
514 1
|
安全 数据库 数据安全/隐私保护
什么是 单点登录SSO?SSO工作原理
单点登录(SSO)让用户通过一组凭证访问多个应用,简化了多平台登录流程。在没有 SSO 的情况下,用户需为每个应用单独管理用户名和密码,而 SSO 通过身份提供商(IdP)和信任的服务提供商(SP)实现统一认证。这不仅减少了用户的密码管理负担,还降低了 IT 管理员的工作量,提高了安全性和用户体验。借助如 ADSelfService Plus 等工具,企业能更轻松地实施 SSO,并结合多重身份验证(MFA)增强安全性。
986 9
|
XML 安全 Java
掌握SpringBoot单点登录精髓,一键通行多系统,轻松打造无缝用户体验新纪元!
【8月更文挑战第29天】单点登录(SSO)是一种身份认证机制,用户在多个相互信任的应用系统中只需登录一次即可访问所有系统,无需重复输入凭证。本文详细介绍如何利用Spring Security和OAuth2在SpringBoot中实现SSO,并提供示例代码。核心步骤包括:引入依赖、配置认证服务器与资源服务器、实现单点登录拦截器及完成SSO配置。通过合理配置,SSO能显著提升用户体验和系统安全性。
1160 2
|
安全 Java 数据安全/隐私保护
在Java项目中集成单点登录(SSO)方案
在Java项目中集成单点登录(SSO)方案
1151 2
|
存储 前端开发 安全
强化用户体验与安全性:前端单点登录和统一认证的最佳实践与区别
互联网发展了这么多年,各种更新皆为了提供更好更安全的上网环境。同时为了提供更好的用户体验、减少用户反复输入用户名和密码的繁琐操作,并确保账户安全,前端领域中的单点登录(SSO)和统一认证(Unified Authentication)成为了重要概念。
强化用户体验与安全性:前端单点登录和统一认证的最佳实践与区别
|
小程序 容灾
单点登录模式
单点登录模式
1590 0
|
存储 安全 数据安全/隐私保护
SSO 单点登录与 OAuth2.0 的技术区别与应用
【8月更文挑战第24天】在现代软件开发和企业信息化建设中,身份认证与授权是不可或缺的一环。SSO(Single Sign-On,单点登录)和OAuth 2.0作为两种重要的身份认证与授权机制,各自具有独特的特点和应用场景。本文将详细探讨这两种机制的区别,并分享在工作学习中的技术干货。
689 0
|
存储 NoSQL Java
10张流程图+部署图,讲透单点登录原理与简单实现
10张流程图+部署图,讲透单点登录原理与简单实现
543 1
10张流程图+部署图,讲透单点登录原理与简单实现