当乐创者报表、电子表格表单等整合到第三方业务系统中时,除了有乐创者一方的用户身份外,很多时候,用户更希望通过第三方平台认证的方式来确保访问的权限。
为了满足这些需求,乐创者开发平台提供了安全认证的接口和基础实现类,业务系统在对接乐创者开发平台时,需要开发一个认证扩展包(里面实现认证相关的业务逻辑),供平台服务程序调用即可。

1 基本原理

第三方业务系统访问乐创者服务进行安全认证的宏观原理图:

第三方业务系统访问智能报表/电子表格表单/多维透视分析/智能分析报告等相关页面时,安全认证的大致流程示例:

注意:不同系统自己的认证方式不同,但总体流程一致。

2 开发认证扩展包

乐创者开发平台提供了安全认证的接口和基础实现类,业务系统在对接乐创者开发平台时,需要开发一个认证一个认证类(里面实现认证相关的业务逻辑,编译后放到乐创者服务classes对应目录下)或者认证扩展包(里面实现认证相关的业务逻辑,最终打包放到乐创者开发平台应用的lib目录下),供平台服务程序调用。

2.1 搭建工程说明

普通jar工程
导入hr-toolkit-6.x.x-SNAPSHOT.jar、hr-privilege-6.x.x-SNAPSHOT.jar等jar包,如下图所示:

Maven工程

<dependency>
    <groupId>com.datanew.happyreport</groupId>
    <artifactId>hr-toolkit</artifactId>
    <version>6.7.1</version>
</dependency>
<dependency>
    <groupId>com.datanew.happyreport</groupId>
    <artifactId>hr-privilege</artifactId>
    <version>6.7.1</version>
</dependency>

2.2 认证接口

public interface IPrivilegeHelper extends Serializable {
    public static final String GET = "GET";
    public static final String POST = "POST";
    /**
     * 执行用户身份有效性认证
     * @param request servlet请求
     * @return 认证成功返回true,认证失败返回false
     */
    public boolean doValidate(HttpServletRequest request);

    /**
     * doValidate认证用过后,动态追加报表参数(如用户身份相关的)
     * @param request 报表客户端请求对象
     * @param reportName 当前报表的名称
     * @param variants URL中传入的报表参数信息,格式:参数名=参数值;参数名=参数值
     * @return 加工后的报表变量串
     */
    public String appendReportVariants(HttpServletRequest request, String reportName, String variants);

    /**
     * 返回从doValidate认证过程中获取到的用户名,或从request中获取用户名
     * @param request 报表客户端请求对象
     * @return 用户名
     */
    public String getUserName(HttpServletRequest request);

    /**
     * 返回包含签名信息的url(由二次开发者实现)
     * @param url 原始url
     * @param headerParams 放入到RequestHead中的参数信息
     * @param sendMothed 请求方式,GET/POST
     * @return 添加签名信息的url
     */
    public String getSignUrl(String url, Map<String,String> headerParams, String sendMothed);

    /**
     * 对数据进行编码处理(由二次开发者实现)
     * @param data 原始数据
     * @return 编码后的数据
     */
    public String encodeData(String data);

    /**
     * doValidate认证用过后,动态追加报表参数(如用户身份相关的)
     * @param data 编码后的数据
     * @return 解码后的数据
     */
    public String decodeData(String data);
}

2.3 构建认证实现类,实现认证方法等

在此工程中,需要创建一个认证实现类,继承PrivilegeHelper,实现IPrivilegeHelper接口,基类中doValidate方法默认是认证通过的,我们可以在自己的实现类中重载此方法,如下所示:

public class ExamplePrivilege extends PrivilegeHelper implements IPrivilegeHelper {
    /**
     * 认证方法
     * @param request servlet请求
     */
    public boolean doValidate(HttpServletRequest request) {
        String userName = null; //用户名 
        /**
         * 从第三方系统中获取登录的用户名或用户身份信息
         */......
        if (获取失败或不允许访问){
            this.setErrMsg("出错提示信息。");
            return false;
        }

        //缓存获取到的用户信息供动态传递用户参数到报表中使用
        this.setValidateParam("userName", userName);
        return true;
    }

    /**
     * doValidate认证用过后,动态追加报表参数(如用户身份相关的)
     * @param request 报表客户端请求对象
     * @param reportName 当前报表的名称
     * @param variants URL中传入的报表参数信息,格式:参数名=参数值;参数名=参数值
     * @return
     */
    public String appendReportVariants(HttpServletRequest request, String reportName, String variants) {
        //假设报表中定义了"userName"这个参数
        String userName = this.getValidateParamValue("userName");
        if (StringUtils.isBlank(variants)) {
            variants = "userName="+userName;
        }else {
            variants += ";userName="+userName;
        }
        return variants;
    }
}

2.4 实现返回用户登录名的方法(可选)

实现代码如下:

/**
 * 返回从doValidate中获取到的用户名,或从request中获取用户名
 * @param request
 * @return
 */
public String getUserName(HttpServletRequest request) {
    String userName = this.getValidateParamValue("userName");
    return userName;
}

3 注册认证类型

sa用户登录乐创者服务,在服务器配置>>系统安全配置>>外部认证配置页面中注册一种认证类型,如下图所示:

上图中的”名称”属性配置为认证实现类的唯一标识名称,拼接报表URL串时需要带入;”类名”属性的值配置为认证实现类的所属包名.类名

4 典型案例

4.1 CAS单点登录

public class ExamplePrivilege extends PrivilegeHelper implements IPrivilegeHelper {
    /**
     * 认证方法
     * @param request servlet请求
     */
    public boolean doValidate(HttpServletRequest request) {
        String userName = null; //用户名 
        /**
         * 调用SSO认证
         */
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        //AbstractCasFilter.CONST_CAS_ASSERTION是CAS中存放登录用户名的session标志  
        //获取CAS服务端设置的用户信息
        Object object = httpRequest.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
        if (object != null) {
            //获取用户信息
            Assertion assertion = (Assertion) object;  
            //获取用户名
            userName = assertion.getPrincipal().getName();
        }
        if(StringUtils.isBlank(userName)) {
            System.out.println("userName 为空");
            this.setErrMsg("认证失败了。");
            this.setErrMsgDetail("SSO认证失败,未获取到userName信息。");
            return false;
        }
        System.out.println(userName);
        //缓存获取到的用户信息供动态传递用户参数到报表中使用
        this.setValidateParam("userName", userName);
        return true;
    }

    /**
     * doValidate认证用过后,动态追加报表参数(如用户身份相关的)
     * @param request 报表客户端请求对象
     * @param reportName 当前报表的名称
     * @param variants URL中传入的报表参数信息,格式:参数名=参数值;参数名=参数值
     * @return
     */
    public String appendReportVariants(HttpServletRequest request, String reportName, String variants) {
        //假设报表中定义了"userName"这个参数
        String userName = this.getValidateParamValue("userName");
        if (StringUtils.isBlank(variants)) {
            variants = "userName="+userName;
        }else {
            variants += ";userName="+userName;
        }
        return variants;
    }
}
作者:柳杨  创建时间:2023-08-08 13:29
最后编辑:柳杨  更新时间:2025-04-22 15:31