springboot 单点登录
lovely好诡异 人气:0什么是单点登录就不用再说了,今天通过自定义sessionId来实现它,想了解的可以参考https://www.xuxueli.com/xxl-sso/
讲一下大概的实现思路吧:这里有一个认证中心,两个单独的服务。每个服务去请求的 时候都要经过一个过滤器,首先判断该请求地址中有没有sessionid,有的话则写入cookie ,如果请求地址中没有sessionid那么从cookie中去获取,如果cookie中获取到了则证明登录了,放行即可。否则跳转到认证中心,此时把请求地址当做参数带到认证中,认证中心认证成功后把sessionid写入cookie,同时重定向带过来的地址,并且把sessionid拼接上。一般直接在认证中心认证过后,直接访问其他系统地址是不会拦截该请求的,所以这个时候可以在跳转到认证页面的时候先判断认证中心这边有没有sessionid,有的话,直接返回,否则再进入认证页面。
语言表达不清楚,下面先来几张图压压惊,看看效果。
没有登录前我访问:http://127.0.0.1:2000/client1
直接跳转到认证页面了
认证成功后
由于我这client系统中登陆过了,所以我直接访问client2,不用登录直接出现了效果
我接下来直接先去认证中心登录一下
此时访问:http://127.0.0.1:2000/client1
效果演示完毕了,下面上代码
Client1代码:
@Controller public class Client1Controller { @GetMapping("/client1") public String client1(){ return "client1"; } }
import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class Client1Filter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponse response = (HttpServletResponse)servletResponse; String parameter = request.getParameter("sso-sessionId"); if(StringUtils.isNotEmpty(parameter)){ Cookie cookie = new Cookie("sso-sessionId", parameter); cookie.setPath("/"); response.addCookie(cookie); } String token=""; Cookie[] cookies = request.getCookies(); if(cookies!=null){ for(Cookie cookie:cookies){ String name = cookie.getName(); if(name.equals("sso-sessionId")){ token = cookie.getValue(); } } } if(StringUtils.isEmpty(token)){ response.sendRedirect("http://127.0.0.1:4000/login?return_url="+request.getRequestURL()); return; } chain.doFilter(servletRequest,servletResponse); } }
由于Client2代码和Client1代码基本一直,所以就不贴上了
认证中心代码
import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.UUID; @Controller public class ServerController { @GetMapping("/login") public String login(String return_url, HttpServletRequest request,HttpServletResponse response) throws IOException { String token=null; Cookie[] cookies = request.getCookies(); if(cookies!=null){ for(Cookie cookie:cookies){ String name = cookie.getName(); if(name.equals("sso-sessionId")){ System.out.println(cookie); token = cookie.getValue(); } } } if(StringUtils.isNotEmpty(return_url)){ if(StringUtils.isNotEmpty(token)){ return_url=return_url+"?sso-sessionId="+token; response.sendRedirect(return_url); } } request.setAttribute("return_url",return_url); return "login"; } @GetMapping("/success") public String success(){ return "success"; } @PostMapping("/doLogin") //@ResponseBody public void doLogin(String userName, String passWord, String return_url, HttpServletResponse response) throws IOException { String token = UUID.randomUUID().toString().replace("-",""); Cookie cookie = new Cookie("sso-sessionId", token); cookie.setPath("/"); response.addCookie(cookie); if(StringUtils.isEmpty(return_url)) { response.sendRedirect("http://127.0.0.1:4000/success"); }else{ return_url=return_url+"?sso-sessionId="+token; response.sendRedirect(return_url); } } }
这样的话,一个简单的单点登录就完成了,至于扩展优化,自行发挥了
加载全部内容