博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
业务系统接入单点登录服务
阅读量:2198 次
发布时间:2019-05-02

本文共 5911 字,大约阅读时间需要 19 分钟。

转载请注明原文地址: 

 

一:单点登录业务接入场景

  对于大型企业,内部有各种各样的办公OA、业务系统,员工使用起来要记住不同系统的账号密码,非常不方便,因此就催生出一种统一管理账号的认证系统,即单点登录系统。

  其作用是,某位员工,在其中一个系统进行登录验证后,再打开其他系统时,就不需要再次登录,直接进入系统,十分方便快捷。

   那怎么才能做到呢?

 

二:接入思路原理

   1、单点登录系统

  首先,我们要有一个单点登录系统,对账号进行统一管理,我们可以将它作为一个微服务进行部署。

  在这个系统中,记录了员工的账号信息,如:工号、姓名、电话等等。

 

  2、业务系统

  在业务系统中,也要有对应的用户账户,因为业务系统的用户只是单点登录系统用户的一个子集或者交集而已。

  并且,业务系统中有自己的一套角色管理以及授权机制。

 

  3、单点登录原理

  1)在登录业务系统时,拦截未登录的请求,重定向到单点登录扫码认证接口;

  2)在单点登录页面扫码或密码登录后,单点登录系统重定向回业务系统,并且在session中携带认证账号信息;

  3)在业务系统通过过滤器,从session中尝试提取账号信息,如果提取到了,则根据账号信息[通常是用户的工号或者loginname];

     然后根据账号信息,从业务系统本身的数据库中查询出对应的用户账户名和登录密码,如果有,则说明此登录用户是本系统用户,直接调用本系统所用的登录校验机制在代码中模拟一遍登录过程,并把登录后状态信息保存到session中即可;如果找不到对应用户,则说明此用户在业务系统没有账号,禁止登入,重定向回系统登录页面或者一个消息提示页面告诉他没有系统账户。

 

三:接入实现

   以下基于Java进行接入说明。

 

  1、添加依赖

  Java的单点登录功能依赖于 cas_client_core 这个jar包,我们可以在pom文件中添加依赖:

org.jasig.cas.client
cas-client-core
3.2.0

 

    2、配置拦截规则

  1)对于非SpringBoot构建的项目,在web.xml中配置以下拦截规则:

org.jasig.cas.client.session.SingleSignOutHttpSessionListener
CAS Single Sign Out Filter
org.jasig.cas.client.session.SingleSignOutFilter
CAS Single Sign Out Filter
/*
CASFilter
org.jasig.cas.client.authentication.AuthenticationFilter
casServerLoginUrl
单点登录系统认证接口
serverName
本业务系统首页地址
CASFilter
/*
CAS Validation Filter
org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
casServerUrlPrefix
单点登录系统认证接口
serverName
本业务系统首页地址
CAS Validation Filter
/*
CAS HttpServletRequest Wrapper Filter
org.jasig.cas.client.util.HttpServletRequestWrapperFilter
CAS HttpServletRequest Wrapper Filter
/*
CAS Assertion Thread Local Filter
org.jasig.cas.client.util.AssertionThreadLocalFilter
CAS Assertion Thread Local Filter
/*

 

  2)对于SpringBoot构建的项目,则需创建一个配置类,在其中通过方法来返回配置bean。

  首先,创建一个类,继承 WebMvcConfigurer,并重写两个方法:

  

  然后,定义过滤器配置方法,注意:一个过滤器定义一个方法,该方法返回一个配置bean:

  方法中要设置的内容,参考web.xml下配置的内容即可。

 

  3、编写业务系统的登录过滤器

  在业务系统处定义一个过滤器,对所有路径进行拦截校验:如果session中已有登录状态,则放行;否则,尝试从session中提取cas认证信息,并进行模拟登录逻辑;如果也没有,则重定向到业务系统登录页面使用户进行登录操作。

@Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        HttpServletRequest re = (HttpServletRequest) request; //获取request        HttpServletResponse resp = (HttpServletResponse) response; //获取respinse            AttributePrincipal attributePrincipal = (AttributePrincipal) re.getUserPrincipal(); //返回一个java.security.Principal  对象,该对象包含当前授权用户的名称        String cas_account = "";        String username = "";        String userpass = "";        //提前session中的登录信息        Object object = re.getSession().getAttribute("_const_cas_assertion_");        if (object != null) {            Assertion assertion = (Assertion) object;            fnumber = assertion.getPrincipal().getName();        } else if (attributePrincipal != null) {            cas_account = (String) attributePrincipal.getName();        }        Users userLogin = (Users) re.getSession().getAttribute("CURRENT_USER");        if (userLogin == null) {            if(cas_account ==null||"".equals(cas_account )){                chain.doFilter(request, response);//本系统通过拦截器进行了登录状态校验,故此处放行,让后面的拦截器进行未登录重定向,而不在此处进行。当然,也可以在此处直接重定向回首页            }        }else{            chain.doFilter(request, response);//若检测到登录信息,则直接放行        }       //检测到cas信息,但是又未登录,则在此处模拟登录过程            try {            if (re.getSession().getAttribute("CURRENT_USER") == null) {                //代码模拟登录过程:根据cas传过来的用户信息,查找本系统用户,拿到账号密码进行登录认证            模拟过程略......各系统不一样,按需实现。                    re.getSession().setAttribute("CURRENT_USER", 当前登录用户);                   resp.sendRedirect("/index?userId="+当前登录用户id);//登录成功,重定向到业务系统首页                        }else {                            if(users.size() == 0){                                logger.error("========users match none!========");//根据cas信息,在本系统没找到匹配用户,则返回系统登录页面或者重定向到一个错误提示页                            }else {                                logger.error("========users match more than one!========");//根据cas信息,在本系匹配到多于一个用户,则返回系统登录页面或者重定向到一个错误提示页                            }                        }                    }                } else {                    if(mobiles.size() == 0){                        logger.error("========mobile match none!========");                    }else {                        logger.error("========mobile match more than one!========");                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }        chain.doFilter(request, response);    }

 

  最后,别忘了将自定义的filter配置到web.xml或者在配置类中书写一个注册方法。

转载于:https://www.cnblogs.com/ygj0930/p/11377620.html

你可能感兴趣的文章
Python 列表(list)、字典(dict)、字符串(string)常用基本操作小结
查看>>
Loadrunner之https协议录制回放报错如何解决?(九)
查看>>
python中xrange和range的异同
查看>>
列表、元组、集合、字典
查看>>
【Python】easygui小甲鱼
查看>>
【Python】关于Python多线程的一篇文章转载
查看>>
【Pyton】【小甲鱼】文件
查看>>
【Pyton】【小甲鱼】永久存储:腌制一缸美味的泡菜
查看>>
【Pyton】【小甲鱼】异常处理:你不可能总是对的
查看>>
APP性能测试工具
查看>>
【Pyton】【小甲鱼】类和对象
查看>>
压力测试工具JMeter入门教程
查看>>
作为一名软件测试工程师,需要具备哪些能力
查看>>
【Pyton】【小甲鱼】类和对象:一些相关的BIF(内置函数)
查看>>
【Pyton】【小甲鱼】魔法方法
查看>>
单元测试需要具备的技能和4大阶段的学习
查看>>
【Loadrunner】【浙江移动项目手写代码】代码备份
查看>>
Python几种并发实现方案的性能比较
查看>>
[Jmeter]jmeter之脚本录制与回放,优化(windows下的jmeter)
查看>>
Jmeter之正则
查看>>