zoukankan      html  css  js  c++  java
  • sso单点登录

    同域下的单点登录:

    现在假设有两个系统demo1,和demo2它们分别有自己的登陆方法如下:

    @PostMapping("/doLogin")
        public String doLogin(String username,String password,String url,HttpServletResponse response){
            boolean result = SSOUtil.loginCheck(username,password);
            if(result){
                Cookie cookie = new Cookie("ssoCookie","sso");//这里的cookie需要一定的规则
                cookie.setDomain(".bxw.com");//将cookie设置为同父域
                cookie.setPath("/");//设置cookie的路径为根路径,也就是同域cookie都有效
                response.addCookie(cookie);
                return "/success";
            }
            return "";
        }

    在父域中设置cookie:cookie.setDomain(".bxw.com");//将cookie设置为同父域

    在SSOUtil类中的loginCheck方法中检验用户名密码的正误,如果检验通过则result的结果为true,这样在本域中会产生键为ssoCookie,值为sso的cookie(在sso中,不同用户的键一般是相同的,而值则根据一定规则生成独属于自己的值,这里为了简便统一写为sso)。

    现在假设demo1系统已经登录,刷新demo2的登陆页面。

    @GetMapping("/")
        public String toLogin(HttpServletRequest request){
         Cookie[] cookies = request.getCookies(); 
    if(SSOUtil.cookieCheck(cookies)){ return "/success"; }else{ return "/login"; } }

    demo2在跳转登录页面的方法中会首先检验是否有键为ssoCookie,值为sso的cookie,如果有的话,则返回登录成功的界面否则返回登陆页面。检验cookie方法如下。

    public static boolean cookieCheck(Cookie[] cookies){
            if(cookies!=null){
                for(Cookie cookie:cookies){
                    if("ssoCookie".equals(cookie.getName()) && "sso".equals(cookie.getValue())){
                        return true;
                    }
                }
            }
            return false;
        }

    同父域下的单点登录:

    与同域下的单点登录类似,只不过在产生cookie时,需要设置cookie的域为父域,具体方法如下:

    @PostMapping("/doLogin")
        public String doLogin(String username,String password,String url,HttpServletResponse response){
            boolean result = SSOUtil.loginCheck(username,password);
            if(result){
                Cookie cookie = new Cookie("ssoCookie","sso");//这里的cookie需要一定的规则
                cookie.setDomain(".bxw.com");//将cookie设置为同父域
                cookie.setPath("/");//设置cookie的路径为根路径,也就是同域cookie都有效
                response.addCookie(cookie);
                return "/success";
            }
            return "";
        }

    需要修改cookie的验证方法,这里我们假设有一个项目demo3专门用来检验cookie。因为子域可以拿到父域的cookie,demo2遍历域中的cookie,拿到键为ssoCookie的cookie发送到demo3进行检验,这里采用http请求。

    @GetMapping("/")
        public String toLogin(HttpServletRequest request){
            Cookie[] cookies = request.getCookies();
            String result = "false";
            if(cookies!=null){
                for(Cookie cookie:cookies){
                    if("ssoCookie".equals(cookie.getName())){
                        Map<String,String> map = new HashMap<String,String>();
                        map.put("name",cookie.getName());
                        map.put("value",cookie.getValue());
                        result = SSOUtil.sendGet("http://client.bxw.com:7777/springboot/sso/checkCookie",map);
                    }
                }
            }
            if("true".equals(result)){
                return "/success";
            }else{
                return "/login";
            }
        }

    检验cookie其实应该写一个过滤器,这里为了方便直接写在跳转登录页面的方法中,一般在参数过多的情况下会采用map传参。

    http请求如下,这里用了get请求。

    public static String sendGet(String url, Map<String,String> cookieMap) {
            String result = "";
            BufferedReader in = null;
            try {
                StringBuffer urlNameString = new StringBuffer(url + "?");
                for(Map.Entry<String,String> tmp:cookieMap.entrySet()){
                    urlNameString.append(tmp.getKey()+"="+tmp.getValue()+"&");
                }
                String urlVal = urlNameString.substring(0,urlNameString.length()-1).toString();
                URL realUrl = new URL(urlVal);
                // 打开和URL之间的连接
                URLConnection connection = realUrl.openConnection();
                // 设置通用的请求属性
                connection.setRequestProperty("accept", "*/*");
                connection.setRequestProperty("connection", "Keep-Alive");
                connection.setRequestProperty("user-agent",
                        "Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 建立实际的连接
                connection.connect();
                // 获取所有响应头字段
                Map<String, List<String>> map = connection.getHeaderFields();
                // 遍历所有的响应头字段
                for (String key : map.keySet()) {
                    System.out.println(key + "--->" + map.get(key));
                }
                // 定义 BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(
                        connection.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            } catch (Exception e) {
                System.out.println("发送GET请求出现异常!" + e);
            }
            // 使用finally块来关闭输入流
            finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
            return result;
        }

    demo3中对demo2发出的http请求处理。

    @GetMapping("/checkCookie")
        public String cookieCheck(HttpServletRequest request){
            String CookieName = request.getParameter("name");
            String CookieValue = request.getParameter("value");
            Boolean flag = false;//验证是否成功
            if(CookieName.equals("ssoCookie") && CookieValue.equals("sso")){
                flag = true;
            }
            return flag.toString();
        }
        /*
        public void cookieCheck(HttpServletRequest request, HttpServletResponse response){
            String CookieName = request.getParameter("name");
            String CookieValue = request.getParameter("value");
            Boolean flag = false;//验证是否成功
            if(CookieName.equals("ssoCookie") && CookieValue.equals("sso")){
                flag = true;
            }
            try{
                response.getWriter().print(flag);
            }catch (IOException e){
                e.printStackTrace();
            }
        }*/

    跨域单点登录:

      如果是跨域的话,在demo2登陆时需要去请求demo1域中的单点登录的cookie拿到用户,如果成功拿到,则登录成功,如果拿不到则返回登陆页面。

  • 相关阅读:
    在mybatis中调用存储过程的时候,不能加工语句
    mybatis sql注入
    关于mybatis缓存配置讲解
    execution(* com.sample.service.impl..*.*(..))
    mybatis中if test 可以使用== != null '' and or 和括号()
    java中可以对时间进行加减处理,有时候不用在sql语句中处理
    【Guava】RateLimiter类
    maven编译报错 -source 1.5 中不支持 lambda 表达式
    easyui打开dialog后给弹出框内输入框赋值问题
    HttpClient 基于连接池的使用
  • 原文地址:https://www.cnblogs.com/popcornya/p/7897019.html
Copyright © 2011-2022 走看看