SSO单点登录
- 原理:①当用户第一次访问应用系统1的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行校验,检查ticket的合法性。如果通过校验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。
- 逐步解析原理
- ①用户第一次访问应用系统时,因为没登录,所以要到认证系统中进行登录。这里实现是通过过滤器,过滤系统1的所有请求,看是否存在凭证(凭证保存在了cookie中)。系统1,2..中过滤器代码如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest request2 = (HttpServletRequest) request; HttpServletResponse response2 = (HttpServletResponse) response; // 通票名称 String token = "token"; boolean flag = true; // 凭证通过Cookie实现 // Cookie的获取 Cookie[] cookies = request2.getCookies(); if (cookies == null) { // 不存在cookie,即不存在凭证,跳转到登录界面 // 重定向到登录界面 response2.sendRedirect("/itdage-sso/login.jsp"); } else { // 存在cookie for (Cookie cookie : cookies) { // 因为前端cookie不止一个,所以判断有没有名字是token的cookie if (token.equals((cookie.getName()))) { //有token,从redis中获取对应的对象,因为SSO中session不能共享,在这用redis代替session存储登录的对象信息。 //redis可以设置过期时间,也是key-value格式存储,完美替代session。 Jedis jedis = new Jedis("localhost"); String objStr = jedis.get(cookie.getValue()); //如果没有token的值还得跳转到登录界面 if(objStr == null){ response2.sendRedirect("/itdage-sso/login.jsp"); flag = false; break; } //从redis中取出value,此处存储value用的是json字符串格式,所有取出时用json转为对象 Gson gson = new Gson(); User user = gson.fromJson(objStr, User.class); //将user设置到session中(单个系统中session还是能用的) HttpSession session = request2.getSession(); session.setAttribute("user", user); //放行 chain.doFilter(request2, response2); //不在执行下面的跳转,否则会报错 flag = false; } } //不存在token,则跳转 if(flag){ response2.sendRedirect("/itdage-sso/login.jsp"); } } } - ②根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,应该返回给用户一个认证的凭据--ticket;
//SSO登录部分后端代码 @Controller public class LoginController { @Resource private LoginService loginService; @Resource private Result result; private Gson gson = new Gson(); private Jedis jedis = new Jedis("localhost"); @ResponseBody @RequestMapping(value="/login", method = RequestMethod.POST) public Result Login(User user, HttpServletRequest request, HttpServletResponse response){ //调用数据库验证,也可写死用户名和密码 List list = loginService.getList(user); if(list.size()>0){ //密码正确,登录成功,保存用户信息 HttpSession session = request.getSession(); //验证验证码是否正确 String vCode = (String)session.getAttribute("vCode"); if(vCode.equalsIgnoreCase(user.getvCode())){ //验证成功标志 result.setState(1); //SSO下要将用户信息存入redis中,redis是session的一个很好的替代品,设置redis的有效时间为30' //生成凭证,要唯一 String token = "Sso_Token" + list.get(0).getUsername() + System.currentTimeMillis(); //将用户信息转为Json字符串存入redis,对应上面的从redis取出。 String value = gson.toJson(list.get(0)); //将用户信息存入redis中 jedis.set(token, value); //设置token_key有效期为30分钟 jedis.expire(token, 30*60); //将token设置到cookie中,因为前端访问后台会自动携带者cookie,所有cookie是存储凭证的好地方。 Cookie cookie = new Cookie("token", token); //这句话很重要,设置cookie有效区间为整个根项目(全局) cookie.setPath("/"); response.addCookie(cookie); }else{ //验证码不正确 result.setObject(user); result.setState(2); } }else{ //密码错误 result.setObject(user); result.setState(3); } return result; } }
3. 此时登录成功后要重定向到用户一开始访问的url,用户登录成功后,再访问其他系统时,会带着生成的cookie,然后过滤器中验证了cookie(凭证)有效,就不用登录啦!
4. 可以结合这个网站理解上面的代码。39.106.45.93/itdage/index.jsp(自己写的小项目)
本文介绍SSO单点登录的基本原理,并通过具体代码示例详细解释其实现过程。用户首次访问应用系统时,若未登录,则被重定向至认证系统;认证通过后,用户获得认证凭据ticket,后续访问其他应用系统时无需重复登录。
596

被折叠的 条评论
为什么被折叠?



