NC集成CAS统一认证+单点登录原理

来源:互联网 发布:网络水军怎么做 编辑:程序博客网 时间:2024/04/28 22:29

原理及步骤:

1、浏览器中输入应用地址http://IP:port/inedx.jsp

进入NC服务器拦截器1处理:如果URI/index.jspticket==null,且Assertion==null,则跳转到CAS认证页面。

2CAS登录成功,跳转回业务系统/index.jsp页面。

进入NC服务器拦截器1处理:此时ticket!=null,流转到拦截器2进行ticket校验。

3、拦截器2校验未通过则终止;通过则设置Assertion(包含用户名等信息),并跳转到/index.jsp;jsessionid=XX。注意此时的URI/index.jsp;jsessionid=XX,而不是/inedx.jsp

4、拦截器1进行处理,此时ticket==nullAssertion!=null,进行ssokey注册和跳转到单点登录地址,CAS单点登录成功。

流程图:


web.xml配置

<!--统一认证 start--><!--用于实现单点退出--><listener><listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class></listener><filter><filter-name>CAS Single Sign Out Filter</filter-name><filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class></filter><filter-mapping><filter-name>CAS Single Sign Out Filter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--该过滤器负责用户的认证工作,判断用户是否登录(必须) start--><filter> <filter-name>CASAuthenticationFilter</filter-name> <filter-class>nc.bs.cas.login.AuthenticationFilter</filter-class> <init-param> <!--注意casServerLoginUrl指服务器的地址 --><param-name>casServerLoginUrl</param-name> <param-value>http://XX:XX</param-value> </init-param> <init-param> <!-- 当指定renew为true时,在请Cas Server时将带上参数“renew=true”,默认为false --><param-name>renew</param-name> <param-value>false</param-value> </init-param> <init-param> <!-- 指定gateway为true时,在请求Cas Server时将带上参数“gateway=true”,默认为false。 --><param-name>gateway</param-name> <param-value>false</param-value> </init-param> <init-param>  <!--而serverName指的是应用的地址 --><param-name>serverName</param-name> <param-value>http://XX:XX</param-value> </init-param></filter><filter-mapping> <filter-name>CASAuthenticationFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping><!--该过滤器负责用户的认证工作 end--><!-- 该过滤器配置负责对Ticket的校验工作,对于client接收到的ticket进行验证(必须) start --><!--这个过滤器可以从ticket取出CAS的session赋值到应用系统--><filter> <filter-name>CASValidationFilter</filter-name> <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> <init-param> <!--注意casServerLoginUrl指服务器的地址 --><param-name>casServerUrlPrefix</param-name> <param-value>http://XX:XX</param-value> </init-param> <init-param> <!--而serverName指的是应用的地址 --><param-name>serverName</param-name> <param-value>http://XX:XX</param-value> </init-param> <init-param> <param-name>useSession</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>redirectAfterValidation</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CASValidationFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 该过滤器配置负责对Ticket的校验工作 end --><!--统一认证 end-->

拦截器1核心代码:

private boolean isExclude(HttpServletRequest request){      boolean isInWhiteList = true;    String uri=request.getRequestURI();    // /index.jsp    // 1. /index.jsp 跳转到CAS认证页面     // 2. /index.jsp 有ticket 认证页面第一次跳回系统时有ticket,让校验器处理    if("/index.jsp".equals(uri)){    isInWhiteList = false;    }    // /index.jsp;jsessionid=82547E908AAE29F76F5D598533818E6D.server    // 3. 校验器处理通过后重定向到系统,/index.jsp;jsessionid或者/;jsessionid    else if(uri!=null&&(uri.startsWith("/index.jsp;jsessionid")||uri.startsWith("/;jsessionid"))){    isInWhiteList = false;    }        return isInWhiteList;    }      @Overridepublic final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)        throws IOException, ServletException    {        HttpServletRequest request = (HttpServletRequest)servletRequest;        HttpServletResponse response = (HttpServletResponse)servletResponse;                if(isExclude(request)){            filterChain.doFilter(request, response);            return;        }                        String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName());                // 只有从认证页面跳回系统那一次请求有ticket        if(CommonUtils.isNotBlank(ticket))        {        log.error("######check ticket, uri="+request.getRequestURI()+", ticket="+ticket);            filterChain.doFilter(request, response);            return;        }            // 存在session则返回,否则返回null        HttpSession session = request.getSession(false);                Assertion assertion = session == null ? null : (Assertion)session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);        if(assertion != null)        {        String user=InvocationInfoProxy.getInstance().getUserCode();        if(isNullStr(user)){        log.error("######register ssoKey, uri="+request.getRequestURI());        String loginName = assertion.getPrincipal().getName();        // 登录NC        String appServer=this.serverName;        if(appServer==null){        appServer=request.getScheme() + "://" + request.getLocalAddr()+":"+request.getLocalPort();        }else if(appServer.endsWith("/")){        appServer=appServer.substring(0, appServer.length()-1);        }        // 1.生成ssoKey        String randomKey = IDMaker.makeID(30);        // 拼接NCURL跳转URL ssoRegServlet?ssoKey=key&userCode=        String regUrl = appServer + "/service/ssoRegServlet?ssoKey=" + randomKey + "&userCode=" + loginName;        // 2.注册ssoKey        try {        registerConnect(regUrl);        } catch (Exception e) {        Logger.error("注册ssoKey时异常", e);        }        // 3.通过ssoKey登录        String newUrl=appServer + "/login.jsp?ssoKey=" + randomKey;        response.sendRedirect(newUrl);        return;        }            filterChain.doFilter(request, response);            return;        }else{                // 控制是否启用CAS统一认证,系统参数异常时不走CAS    try {    List<SysInitVO>list=(List<SysInitVO>) getDao().retrieveByClause(SysInitVO.class, "initcode ='" + SQLTransferMeaningUtil.tmsql(AuthenticationFilter.PARAM_CAS) + "'and pk_org='" + SQLTransferMeaningUtil.tmsql(IOrgConst.GLOBEORG) + "'");       if(list!=null&&list.size()>0){    UFBoolean cas=new UFBoolean(list.get(0).getValue());    if(cas!=null&&cas.booleanValue()==false){    filterChain.doFilter(request, response);                return;    }    }} catch (Exception e1) {Logger.error("获取系统参数错误", e1);filterChain.doFilter(request, response);            return;}        log.error("######sendRedirect to cas, uri="+request.getRequestURI());            Logger.debug("no ticket and no assertion found");                String serviceUrl = constructServiceUrl(request, response);        String modifiedServiceUrl;        if(gateway)        {        Logger.debug("setting gateway attribute in session");            modifiedServiceUrl = gatewayStorage.storeGatewayInformation(request, serviceUrl);        } else        {            modifiedServiceUrl = serviceUrl;        }                String urlToRedirectTo = CommonUtils.constructRedirectUrl(casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, renew, gateway);                // 重定向        response.sendRedirect(urlToRedirectTo);        return;        }    }


原创粉丝点击