历史版本52 :配置FineReport作为CAS客户端 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

目录:

1. 概述编辑

本文介绍如何配置 FineReport 作为 CAS 客户端。

1.1 环境检查

在配置 FineReport 之前,需检查以下配置:

1)CAS 服务器环境确认,若无该环境,可参考参考 CAS 服务器搭建 进行安装配置。

2)配置 SSL 证书实现 HTTPS 访问

3)若用户需要使用数据库中国的信息进行登录验证,可参考 实现基于数据库的身份验证 进行配置。

1.2 配置原理

CAS 单点登录 过程中,根据客户端承担的主要功能,对 FineReport 进行相应配置。

1)用户访问数据决策系统时,将请求重定向到 CAS 服务器。

2)向 CAS 服务器验证 ticket 的真实性,是否过期等信息。

3)获取 CAS 认证返回的用户名,并且和 FineReport 中的用户进行对比,对比一致,且用户可用,则单点登录成功。

登录认证流程如下图所示:

2. 操作步骤编辑

2.1 拷贝 JAR 包

将 CAS 的casclient.jarcas-client-core-3.2.1.jarJAR 包以及%Java_HOME%\jdk\lib\tools.jar都拷贝到%TOMCAT_HOME%\webapps\webroot\WEB-INF\lib下,如下图所示:

1587349588839090.png

2.2 添加 web.xml

web.xml 文件用来实现以下功能:

  • 用户访问数据决策系统时,将请求重定向到 CAS 服务器。

  • 向 CAS 服务器验证 ticket 的真实性,是否过期等信息。

%TOMCAT_HOME%\webapps\webroot\WEB-INF目录下新建web.xml 文件,插入以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
   xmlns="http://java.sun.com/xml/ns/j2ee" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
   version="2.4"> 
  <display-name>Template WebApp</display-name>
    <mime-mapping>
  <extension>msi</extension>
  <mime-type>application/x-msi</mime-type>
  </mime-mapping>     
  <filter>  
        <filter-name>CASFilter</filter-name>  
        <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>  
        <init-param>  
            <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>  
            <param-value>https://roxy:8443/cas/login</param-value>  
            <!--cas提供登录页面的url-->  
        </init-param>  
        <init-param>  
            <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>  
            <param-value>https://roxy:8443/cas/proxyValidate</param-value>  
            <!--cas提供service ticker或者proxy ticket验证服务的url-->  
        </init-param>  
        <init-param>  
            <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>  
            <param-value>roxy:8443</param-value>  
                        <!--客户端应用的域名和端口-->  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>CASFilter</filter-name>  
        <url-pattern>/decision/*</url-pattern>  
    </filter-mapping> 
 <filter>    
    <filter-name>FrFilter</filter-name>    
    <filter-class>com.fr.FrFilter</filter-class>    
</filter>    
<filter-mapping>    
    <filter-name>FrFilter</filter-name>    
    <url-pattern>/decision/*</url-pattern>    
</filter-mapping>  
</web-app>

其中 roxy 为个人配置的域名,请按照个人设置进行修改,如下图所示所示:

1587363379230150.png

2.3 新建 Java 文件

Fr.Filter 用来获取 CAS 认证返回的用户名,并且和 FineReport 中的用户进行对比,判断是否为数据决策系统的用户。

1)新建 Java 文件,命名为 FrFilter.java 。完整的 Java 代码如下所示:

package com.fr;
import com.fr.data.NetworkHelper;
import com.fr.decision.mobile.terminal.TerminalHandler;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.security.JwtUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import org.jasig.cas.client.validation.Assertion;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
 * Created by Zed on 2018/9/11.
 */
public class FrFilter implements Filter {
    public FrFilter() {
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        FineLoggerFactory.getLogger().info("fr cas login");
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;
        HttpSession session = req.getSession(true);
        FineLoggerFactory.getLogger().info("URL:" + req.getRequestURI());
        String username;
        //获取cas传递过来的username
        Object object = req.getSession().getAttribute("_const_cas_assertion_");
        if (object != null) {
            Assertion assertion = (Assertion) object;
            username = assertion.getPrincipal().getName();
        } else {
            username = (String) session.getAttribute("edu.yale.its.tp.cas.client.filter.user");
        }
        try {
            //用户名为空,登录请求有问题,直接报错
            if (StringUtils.isNotEmpty(username)) {
                FineLoggerFactory.getLogger().info("username:" + username);
                //获取请求携带的token
                Object oldToken = session.getAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME);
                //token不存在,或者token过期了,走后台登录方法
                if (oldToken == null || !checkTokenValid(req, (String) oldToken, username)) {
                    login(req, res, session, username);
                    filterChain.doFilter(req, res);
                } else {
                    //放行
                    filterChain.doFilter(req, res);
                    FineLoggerFactory.getLogger().info("no need");
                }
            } else {
                throw new Exception("username is empty");
            }
        } catch (Exception e) {
            FineLoggerFactory.getLogger().error(e.getMessage(), e);
        }
    }
    /**
     * 后台登录方法
     */
    private void login(HttpServletRequest req, HttpServletResponse res, HttpSession session, String username) throws Exception {
        String token = LoginService.getInstance().login(req, res, username);
        req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
        FineLoggerFactory.getLogger().info("fr FrFilter is over with username is ###" + username);
    }
    /**
     * 校验token是否有效
     */
    private boolean checkTokenValid(HttpServletRequest req, String token, String currentUserName) {
        try {
            //当前登录用户和token对应的用户名不同,需要重新生成token
            if (!ComparatorUtils.equals(currentUserName, JwtUtils.parseJWT(token).getSubject())) {
                FineLoggerFactory.getLogger().info("username changed:" + currentUserName);
                return false;
            }
            Device device = NetworkHelper.getDevice(req);
            LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
            return true;
        } catch (Exception ignore) {
        }
        return false;
    }
    @Override
    public void destroy() {
    }
}

2)编译 FrFilter.java ,将生成的 FrFilter.class 文件放在%TOMCAT_HOME%\webroot\WEB-INF\classes\com\fr目录下,如下图所示:

点击下载并解压获得 FrFilter.class 文件:FrFilter.zip

1587350278256926.png

3. 效果查看编辑

启动 Tomcat 服务器,在浏览器中输入:https://localhost:8443/webroot/decision即进入了 CAS 登录界面,输入用户名和密码即可跳转到数据决策系统对应的用户界面下,如下图所示:

1619664423960713.png