最新历史版本 :配置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