主题
[TOC]
认证方式
用户登录衡石系统时,系统需要对输入的用户名和密码进行验证,保证系统的安全。衡石提供 CAS、SAML2、OAUTH2等多种单点登录认证方式。在 SSO 单点登录中,衡石是服务提供者 SP(Service Provider)为用户提供所需服务的一方,通过用户身份提供者 IDP(Identity Provider)来实现用户身份验证。 使用认证服务前请确保 IDP 与 SP 之间能够相互通信。
配置 Base URL
Base URL 在登录认证有重要的作用,配置认证前请先设置 Base URL。
认证方式配置
在系统设置->认证方式
中设置用户登录系统的认证方式。目前支持 HENGSHI、LDAP、CAS、SAML2、OAUTH2、钉钉、企业微信、CTR、云之家、JWT 请求参数、飞书、勤策等多种认证方式。
用户通过认证方式登录到系统的同时还会将用户的一些信息通过配置项同步到系统中, 比如同步用户属性、组织架构到衡石系统中。 本文将这些配置项统称为通用配置项,会在通用配置中统一进行说明。
HENGSHI
HENGSHI 内置的用户认证系统,通过平台内部的用户信息进行身份验证。即使设置为其他认证方式,HENGSHI 系统管理员仍可以通过访问/login 页面来登录。
LDAP
用户使用 LDAP 认证服务器存储用户信息,希望通过同样的认证方法登录衡石系统时可以选择 LDAP 认证方式。使用 LDAP 认证时,需要在系统设置->认证方式
中勾选 LDAP 配置并进行 LDAP 相关配置。
LDAP 基础配置包括:
- 协议类型包括 ldap 和 ldaps。
- 主机地址。
- 端口。
- 用户名。
- 密码。
- 搜索库。
- LDAP 查询。
LDAP 通用配置包括用户名映射、显示名映射、邮箱映射、手机号映射、角色映射、组映射、组织架构映射、企业 ID 映射、企业名称映射、平台方 ID、启用 SSO exp 会话有效期同步、会话有效期映射。 通用配置字段的说明和使用请参考通用配置章节。
CAS
用户使用 CAS 认证服务器存储用户信息,希望通过同样的认证方法登录衡石系统时可以选择 CAS 认证方式。使用 CAS 认证时,需要在系统设置->认证方式
中勾选 CAS 配置并进行 CAS 相关配置。
CAS 基础配置包括:
- 协议类型 。
- CAS 服务器地址。
- Reload User。
CAS 通用配置包括显示名映射、邮箱映射、手机号映射、角色映射、组映射、组织架构映射、企业 ID 映射、企业名称映射、平台方 ID、启用 SSO exp 会话有效期同步、会话有效期映射。 通用配置字段的说明和使用请参考通用配置章节。
SAML2
用户使用 SAML2认证服务器存储用户信息,希望通过同样的认证方法登录衡石系统时可以选择 SAML2认证方式。使用 SAML2认证时,需要在系统设置->认证方式
中勾选 SAML2配置并进行 SAML2相关配置。
SAML2 认证相关配置有:
- idpMetadataUrl。
- 私钥。
- 证书。
- entityID。
- Reload User。
SAML2 用于同步用户属性等信息的通用配置有:用户名映射、显示名映射、邮箱映射、手机号映射、角色映射、组映射、组织架构映射、企业 ID 映射、企业名称映射、平台方 ID、启用 SSO exp 会话有效期同步、会话有效期映射。通用配置字段的说明和使用请参考通用配置章节。
OAuth2
用户使用 Oauth2认证服务器存储用户信息,希望通过同样的认证方法登录衡石系统时可以选择 Oauth2认证方式。使用 Oauth2认证时,需要在系统设置->认证方式
中勾选 Oauth2配置并进行 Oauth2相关配置。
OAUTH2 认证相关配置有:
- Client Id,是指 Oauth Server 注册的客户端 Id,也有些系统会叫 App Id,不同的 Oauth Server 叫法会有不同。
- Client Secret,是指 Oauth Server 注册的客户端 Secret,也有些系统会叫 App Secret。
- Authorize 接口,当系统发现用户没有登录,会跳转到该地址,输入用户名密码在 Oauth Server 登录。登录成功后 Oauth Server 会重定向到 HENGSHI 传递的 redirect_uri,并加上 code 参数。
- Token 接口,HENGSHI 系统通过 code 参数向该接口请求 Token,
- User-info 接口,HENGSHI 系统通过 Token 向该接口请求用户基本信息。
- Logout 接口,HENGSHI 系统退出登录时,重定向到该接口,在 Oauth Server 退出登录。有些 Oauth Server 并没有实现该接口。
- Logout 接口拼接 Redirect URI,默认为 true,HENGSHI 系统退出登录时,是否将登出前访问 HENGSHI 的地址拼接到 Logout 接口。
- 登出后跳转地址参数名,默认为 redirect_uri,HENGSHI 系统向 Oauth Server 发出退出登录 Oauth Server 请求时传递, Oauth Server 退出登录后重定向到该地址。
- Scope,由 Oauth Server 定义,配置在 HENGSHI SENSE 系统中,HENGSHI 系统在请求 code 参数时传递。新版本的 Oauth Server keycloack(19.0.2及以上)需要配置 scope,值为
openid
。 - 原始 url 传递方式,是指记录用户原始的请求地址的方式,比如用户输入的 Url 为
http://{host}:{port}/apps/1/dashboard/1
, 在用户登录成功以后会跳转到该地址。一般是记录到 session 中,在多个 iframe 嵌入页面同时打开的场景,需要配置在 url 中传递。 - 校验原始 url ,原始 url 是指用户登录前的原始请求地址,如选择 true,则会检查原始 url 是否以 base url 开头。
- Reload User,是否每次刷新页面都需要重新从 Oauth Server 获取当前登录用户。具体使用场景见认证方式集成说明。
Logout 相关说明及示例(下述网址仅为示例) :
- 如果未配置Logout 接口,则仅登出 HENGSHI。
- 配置Logout 接口
http://logout.com
,并且 Logout 接口拼接 Redirect URI 为 true,则会根据登出后跳转地址参数名拼接登出后的跳转 URL,拼接后为http://logout.com?redirect_uri=http://hengshi.com&activeAuth=oauth2&tenantId=xxxx
,redirect_uri 会进行编码,此处为了展示使用明文, 参数名是否是 redirect_uri 以登出后跳转地址参数名配置为准。 - 新版本的 keycloak 登出参数 redirect_uri 有变化, redirect_uri 变更说明 。如果配置Logout 接口, 并且 Logout 接口拼接 Redirect URI 为 false,keycloak 需要用户点击确认登出。Logout 接口拼接 Redirect URI 为 true,登出后跳转地址参数名 为
post_logout_redirect_uri
登出行为不需用户确认。keycloak 的参数及行为有可能版本区别,详情请查阅 keycloak 文档。
OAuth2 用于同步用户属性等信息的通用配置有:用户名映射、显示名映射、邮箱映射、手机号映射、角色映射、组映射、组织架构映射、企业 ID 映射、企业名称映射、平台方 ID、启用 SSO exp 会话有效期同步、会话有效期映射。通用配置字段的说明和使用请参考通用配置章节。
钉钉
钉钉认证方式支持扫码登录和微应用免登。
钉钉认证相关配置包括:
配置项 | 是否必填 | 说明 |
---|---|---|
AppKey | 是 | 钉钉微应用的基本信息,可参考钉钉配置微应用章节获取 |
AppSecret | 是 | 钉钉微应用的基本信息,可参考钉钉配置微应用章节获取 |
CorpId | 否 | 如果管理员需要在钉钉应用管理后台免登,则需要配置该信息。CorpId,SSOsecret 请参考 钉钉配置微应用章节获取。 |
SSOsecret | 否 | 如果管理员需要在钉钉应用管理后台免登,则需要配置该信息。CorpId,SSOsecret 请参考 钉钉配置微应用章节获取。 |
登录方式 | 是 | 配置默认的登录方式,即在 url 中没有指定时起作用的方式。authCode 是微应用免登,扫码是通过扫描二维码登录 |
同步频率 | 否 | 对组织架构同步进行配置,单位为分钟,0为不同步。如果需要组织架构同步,则必须要配置 AppKey 和 AppSecret 并且应用要开通权限管理中的通讯录权限 |
钉钉用于同步用户属性等信息的通用配置有用户名映射、显示名映射、邮箱映射、手机号映射。 通用配置字段的说明和使用请参考通用配置章节。
钉钉配置微应用
下面描述如何在钉钉开发者平台上创建及配置微应用。
获取钉钉的CorpId 和 SSOSecret
在钉钉的 开发体验账号管理中获取 钉钉 CorpId 和 SSOSecret
https://open-dev.dingtalk.com/fe/old?hash=%23%2FcorpAuthInfo#/corpAuthInfo
在
钉钉开发者后台 -> 应用开发 -> H5微应用
中点击创建应用。在基础信息中可以查看获取到 AppKey,AppSecret。 这两个信息需要同步到 HENGSHI SENSE 系统钉钉配置页面的同名配置字段中。
添加应用能力
网页 H5应用配置
配置项 格式 说明 应用首页地址 http://{host}:{port}/?activeAuth=dingtalk&dtLoginType=authCode&corpId={corpId} dtLoginType=authCode PC 端首页地址 http://{host}:{port}/?activeAuth=dingtalk&dtLoginType=authCode&corpId={corpId} dtLoginType=authCode 管理后台地址 http://{host}:{port}/?activeAuth=dingtalk&dtLoginType=code&corpId={corpId} dtLoginType=code 请注意
- {corpId} 需要替换成 正确的 corpId 值
- 如果租户配置钉钉,需要增加 tenantCode 或者 tenantId 参数(建议使用 tenantId )。格式如下: http://{host}:{port}/?activeAuth=dingtalk&dtLoginType=authCode&corpId={corpId}&tenantId={tenantId}
- tenantId 是新建租户后自动生成的
安全设置
配置项 说明 服务器出口 IP 填写服务器出口 ip(可以通过 https://www.ip138.com/
查询,或者联系网络管理员获得)重定向 URL(回调域名) 衡石服务的 baseURL 端内免登地址 按需填写 权限管理
目前已知需要的权限如下:
权限信息 权限点 code 通讯录部门信息读权限 qyapi_get_department_list 成员信息读权限 qyapi_get_member 通讯录个人信息读取权限 Contact.User.Read 企业员工手机号信息 fieldMobile 邮箱等个人信息 fieldEmail 请注意
钉钉的权限管理可能会发生变化,具体参考钉钉的官方说明
版本管理与发布
可根据需要设置应用发布的使用范围,只有在范围中的人员才可以看到该应用。
请注意
钉钉微应用相关的文档图片可能会有变动,以钉钉官方为准。
企业微信
企业微信认证方式支持扫码登录和微应用免登。
企业微信认证相关配置包括:
- 企业 ID,AgentId,Secret:企业微信的基本信息,可参考企业微信配置自建应用章节获取。
- 登录方式:是配置默认的登录方式,即在 url 中没有指定时起作用的方式。 oauth 是应用免登,扫码是通过扫描二维码登录。
企业微信认证用于同步用户属性等信息的通用配置有用户名映射、显示名映射、邮箱映射、手机号映射。 通用配置字段的说明和使用请参考通用配置章节。
企业微信配置自建应用
- 进入企业微信应用管理->应用->自建,点击创建应用。
- 配置应用 logo,应用名称,应用介绍,可见范围。
- 配置应用。
- 将 AgentId,Secret 配置到 HENGSHI SENSE 系统企业微信配置页面的同名字段中。
- 配置应用主页,如
http://local.hengshi.org:8080?activeAuth=wechat-work&wcwLoginType=oauth2&tenantCode={tenantCode}
。 其中 activeAuth,wcwLoginType 为固定值,可以实现在企业微信中点击 HENGSHI 应用免登陆。如果是租户使用,需要增加 tenantCode,或者 tenantId 参数。 - 配置网页授权及 JS-SDK 中的可信域名。
- 如果需要网页扫码登录功能,需要配置企业微信授权登录中的授权回调域。
企业微信认证方式相关文档,可以参考:
请注意
企业微信文档可能会有变动,以企业微信官方文档为准。
CTR
CTR 是为客户定制的一种认证方式,该认证方式与客户自研的 SSO 系统对接。
云之家
如果使用金蝶云之家应用,并且在云之家做报销审批和报表分析的工作。可以通过配置云之家认证,在云之家上访问对应的报表内容。
报表的入口就是在云之家创建一个应用入口。根据云之家提供的集成 API,做一个 SSO 认证,在云之家应用中直接配置报表的 URL 地址,在云之家应用中免登录打开报表就可以了。
配置方法:
在云之家 (www.yunzhijia.com) 申请成为系统管理员,或由他人邀请,并设为系统管理员。
成为系统管理员后,通过管理中心->应用中心->轻应用管理,进入轻应用管理页面。
选择新建应用,在打开的页面填入信息,红框处 URL 为衡石系统的 url,末尾加上 activeAuth=yunzhijia。如果是租户使用需要 填写 tenantCode 或者 tenantId 参数,示例
http://192.168.3.226:8080/?activeAuth=yunzhijia&tenantCode=tenant1#/publish
。保存后会生成 APPId 和 APPSecret。
在衡石系统中,设置->认证方式->YUN ZHI JIA 中配置 APP ID , APPSecret。
JWT 请求参数
JWT 请求参数是指用户访问系统时,按照 jwt 规范,将用户基本信息进行签名/加密,通过 url 传递给服务器,兼顾安全性和便利性。
JWT 请求参数认证相关配置包括:
- JWT Token 名称。
- 验签算法,客户端签名时与 HENGSHI 配置保持一致。
- 验签密钥,验签算法为 HS256时,客户端与 HENGSHI 配置保持一致。验签算法为 RS256时,客户端使用私钥签名,HENGSHI 配置中填写公钥。
- 验签密钥使用 base64解码。
- 解密方法,客户端加密时与 HENGSHI 配置保持一致。
- 解密算法,客户端加密时与 HENGSHI 配置保持一致。
- 解密密钥,客户端使用公钥加密,HENGSHI 配置中填写私钥。
- 访问系统的 URL 为 http://{host}:{port}/?activeAuth=jwt-param&jwtParam={签名/加密后的 jwt 字符串}
- groovy script:登录过程配置用户登录后的默认角色,默认情况下用户登录后的角色为数据查看。
JWT 请求参数相关参考资料。
JWT 请求参数用于同步用户属性等信息的通用配置有用户名映射、显示名映射、邮箱映射、手机号映射、角色映射、组映射、组织架构映射、企业 ID 映射、企业名称映射、平台方 ID、启用 SSO exp 会话有效期同步、会话有效期映射、groovy script 等。 通用配置字段的说明和使用请参考通用配置章节。
JWT 基本格式说明
JWT 标准中的部分声明:
声明 | 含义 | 是否必须 | 处理逻辑及限制 |
---|---|---|---|
iss | jwt 签发者 | 否 | 无 |
sub | jwt subject | 是 | 非空唯一,如果没有 loginName/email 的映射配置,则 HENGSHI 将该值做为用户的唯一标示。如果有 loginName/email 的映射配置则忽略该值。建议用户使用 loginName/email 的映射配置,sub 的值与 loginName/email 的值相同 |
exp | jwt 的过期时间 | 否 | 过期则该 jwt 无效 |
自定义声明:
声明 | 含义 | 处理逻辑及限制 |
---|---|---|
有映射配置自定义的声明 | 在 HENGSHI 系统中配置了映射关系 | HENGSHI 会根据映射关系保存到用户相应的字段上,如下例中的 loginName=alice,在 HENGSHI 登录名映射配置为 loginName,则会将 alice 做为 HENGSHI 中用户的 loginName。其他的参考 通用配置 |
无映射配置自定义的声明 | 没有在 HENGSHI 系统中配置映射关系 | HENGSHI 会将该类信息保存到用户属性中 ,如下例中的 abc=123,在 HENGSHI 没有映射配置,则会保存为用户的属性信息中 |
JWT 是由三段信息构成的,将这三段信息文本用"."链接一起就构成了 JWT 字符串。以下为示例
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGljZS1zdWJqZWN0IiwiYWJjIjoiMTIzIiwicm9sZXMiOlsic3lzdGVtIGFkbWluIiwiZGF0YSBhZG1pbiIsImRhdGEgYW5hbHlzdCIsImRhdGEgdmlld2VyIiwiYXBpIGFkbWluIl0sImxvZ2luTmFtZSI6ImFsaWNlIn0.PGA9DNa-B_4e4WS-fVG57tvxYe0dlu0r8O_Lw1vEtAQ
1
- 第一部分是 header,明文是
{"typ":"JWT","alg":"HS256"}
,经过 base64URL 编码之后是eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
- 第二部分是 payload,明文是
{"sub":"alice-subject","abc":"123","roles":["system admin","data admin","data analyst","data viewer","api admin"],"loginName":"alice"}
(其中 loginName,roles,abc 都是自定义的示例信息,可以根据需要增加修改),经过 base64URL 编码之后是eyJzdWIiOiJhbGljZS1zdWJqZWN0IiwiYWJjIjoiMTIzIiwicm9sZXMiOlsic3lzdGVtIGFkbWluIiwiZGF0YSBhZG1pbiIsImRhdGEgYW5hbHlzdCIsImRhdGEgdmlld2VyIiwiYXBpIGFkbWluIl0sImxvZ2luTmFtZSI6ImFsaWNlIn0
- 第三部分是 signature,由第一部分的 header+"."+第二部分的 payload 得到需要签名的信息是
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGljZS1zdWJqZWN0IiwiYWJjIjoiMTIzIiwicm9sZXMiOlsic3lzdGVtIGFkbWluIiwiZGF0YSBhZG1pbiIsImRhdGEgYW5hbHlzdCIsImRhdGEgdmlld2VyIiwiYXBpIGFkbWluIl0sImxvZ2luTmFtZSI6ImFsaWNlIn0
,经过相应签名算法签名以后(在本例中就是 HS256),再通过 base64URL 编码得到签名是PGA9DNa-B_4e4WS-fVG57tvxYe0dlu0r8O_Lw1vEtAQ
以上为 jwt 生成过程的基本说明,具体细节以及实现库可以通过JWT 官网进一步了解。
java 示例依赖库:
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>5.4</version>
</dependency>
1
2
3
4
5
2
3
4
5
java 示例代码:
java
import com.nimbusds.jose.EncryptionMethod;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.JWEHeader;
import com.nimbusds.jose.JWEObject;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.RSAEncrypter;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
public class Test {
public static void main(String[] args) throws Exception {
//HS256 hmac 签名
hmacSign();
System.out.println("------------------------------------------");
//RS256 rsa 签名
rsaSign();
System.out.println("------------------------------------------");
//A128CBC-HS256 RSA-OAEP-256 加密
signAndEncrypt();
}
//RS256
public static void rsaSign() throws NoSuchAlgorithmException, JOSEException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
KeyPair kp = kpg.genKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
JWTClaimsSet claimsSet = getJwtClaimsSet();
JWSSigner signer = new RSASSASigner(privateKey);
SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT).build(), claimsSet);
signedJWT.sign(signer);
String token = signedJWT.serialize();
String url = "http://{host}:{port}?activeAuth=jwt-param&jwtParam=" + token;
System.out.println(url);
//验签密钥 在 hengshi 系统中配置
System.out.println("验签密钥=" + Base64.getEncoder().encodeToString(publicKey.getEncoded()));
}
//HS256
public static void hmacSign() throws Exception {
JWTClaimsSet claimsSet = getJwtClaimsSet();
String key = "4b117a14-c652-410a-83b2-9839c16e7ae1";//hs256 密钥 ,必须大于32位
SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.HS256).type(JOSEObjectType.JWT).build(), claimsSet);
JWSSigner signer = new MACSigner(key);
signedJWT.sign(signer);
String token = signedJWT.serialize();
String url = "http://{host}:{port}?activeAuth=jwt-param&jwtParam=" + token;
System.out.println(url);
//验签密钥 配置到 hengshi 系统中
System.out.println("验签密钥=" + key);
/*
备注:签名内容不同,token 也不相同,下面的 token 是根据上面代码中的内容生成的,如果有修改,则 token 也会发生变化
生成的 token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGljZS1zdWJqZWN0IiwiYWJjIjoiMTIzIiwicm9sZXMiOlsic3lzdGVtIGFkbWluIiwiZGF0YSBhZG1pbiIsImRhdGEgYW5hbHlzdCIsImRhdGEgdmlld2VyIiwiYXBpIGFkbWluIl0sImxvZ2luTmFtZSI6ImFsaWNlIn0.PGA9DNa-B_4e4WS-fVG57tvxYe0dlu0r8O_Lw1vEtAQ
示例请求 url:http://{host}:{port}?activeAuth=jwt-param&jwtParam=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGljZS1zdWJqZWN0IiwiYWJjIjoiMTIzIiwicm9sZXMiOlsic3lzdGVtIGFkbWluIiwiZGF0YSBhZG1pbiIsImRhdGEgYW5hbHlzdCIsImRhdGEgdmlld2VyIiwiYXBpIGFkbWluIl0sImxvZ2luTmFtZSI6ImFsaWNlIn0.PGA9DNa-B_4e4WS-fVG57tvxYe0dlu0r8O_Lw1vEtAQ
*/
}
private static JWTClaimsSet getJwtClaimsSet() {
List<String> roles = new ArrayList<>();
roles.add("system admin");//系统管理员
roles.add("data admin");//数据管理员
roles.add("data analyst");//数据分析员
roles.add("data viewer");//数据查看者
roles.add("api admin");//API 管理员
String loginName = "alice";//登录名,唯一
JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
.subject(loginName + "-subject") //jwt 主题,jwt 要求不能为空,如果没有配置登录名映射,会默认取该值作为登录名。要求唯一,可以与登录名相同
//.issuer("https://c2id.com") //颁发者身份标识,表示 Token 颁发者的唯一标识,一般是一个 http(s) url,hengshi 中没有使用
.claim("roles", roles)
/*登录名,唯一,key 可以设置为任意的名称,需要在 hengshi 【jwt 参数认证】方式中配置登录名映射,如此处应配置登录名映射为 loginName
* hengshi 中还可以配置邮箱,手机,角色,用户组等映射,详情请参考文档*/
.claim("loginName", loginName)
.claim("abc", "123") //可以根据需要增加 claim,都会作为用户属性保存
//.expirationTime(new Date(new Date().getTime() + 60 * 1000)) //有效期,根据需要设置
.build();
return claimsSet;
}
public static void signAndEncrypt() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
KeyPair signkp = kpg.genKeyPair();
RSAPrivateKey signPrivateKey = (RSAPrivateKey) signkp.getPrivate();
RSAPublicKey signPublicKey = (RSAPublicKey) signkp.getPublic();
//验签密钥 配置到 hengshi 系统中
System.out.println("验签密钥=" + Base64.getEncoder().encodeToString(signPublicKey.getEncoded()));
JWTClaimsSet jwtClaimsSet = getJwtClaimsSet();
SignedJWT signedJWT = new SignedJWT(
new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT).build(),
jwtClaimsSet);
signedJWT.sign(new RSASSASigner(signPrivateKey));
KeyPair encryptKP = kpg.genKeyPair();
RSAPrivateKey encryptPrivateKey = (RSAPrivateKey) encryptKP.getPrivate();
//解密密钥 配置到 hengshi 系统中
System.out.println("解密密钥=" + Base64.getEncoder().encodeToString(encryptPrivateKey.getEncoded()));
RSAPublicKey encryptPublicKey = (RSAPublicKey) encryptKP.getPublic();
JWEObject jweObject = new JWEObject(
new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128CBC_HS256).type(JOSEObjectType.JWT)
.contentType("JWT")
.build(),
new Payload(signedJWT));
jweObject.encrypt(new RSAEncrypter(encryptPublicKey));
String token = jweObject.serialize();
String url = "http://{host}:{port}?activeAuth=jwt-param&jwtParam=" + token;
System.out.println(url);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
飞书
飞书认证方式支持扫码登录、微应用免登和管理后台免登录。
飞书认证相关配置包括:
- App ID,App Secret: 飞书的基本信息,可参考飞书配置自建应用获取。
飞书配置自建应用
进入开发者后台 -> 企业自建应用 -> 点击企业自建应用。
填写应用名称,应用描述。
在企业自建应用列表中,点击进入刚刚创建的应用,应用信息完善,编辑综合信息。 上传应用图标。 可根据需要填写管理后台主页
http://{host}:{port}?activeAuth=lark&larkLoginType=larkAdminBackend
,该地址是从飞书管理后台免登录进入系统时使用的。具体地址可以根据需要修改,activeAuth,larkLoginType 两个参数是固定的。 如过没有该需求可以不填写。配置应用功能,网页,填写桌面端主页和移动端主页,具体地址可以根据需要修改,activeAuth,larkLoginType 两个参数是固定的。 桌面端主页
http://{host}:{port}?activeAuth=lark&larkLoginType=desktop
移动端主页
http://{host}:{port}?activeAuth=lark&larkLoginType=app
安全设置,配置重定向 URL。
http://{host}:{port}/lark/callback
权限管理,开通权限:以应用身份读取通讯录(contact:contact:readonly_as_app);获取用户邮箱信息(contact:user.email:readonly);获取用户 user ID(contact:user.employee_id:readonly);获取用户手机号(contact:user.phone:readonly)等权限(详情参考表格) 其中获取用户邮箱信息,获取用户 user ID,获取用户手机号为可选权限,如不开通,则飞书不返回以上信息。
飞书需要权限一览表:
权限名称 | code | 说明 |
---|---|---|
获取用户可用的应用 | admin:app.user_usable:readonly | |
获取用户组织架构信息 | contact:user.department:readonly | |
获取用户邮箱信息 | contact:user.email:readonly | |
获取用户 user ID | contact:user.employee_id:readonly | |
获取用户组信息 | contact:group:readonly | |
通过手机号或邮箱获取用户 ID | contact:user.id:readonly | |
获取用户手机号 | contact:user.phone:readonly | |
获取用户性别 | contact:user.gender:readonly | |
查询用户职级 | contact:user.job_level:readonly | |
查询用户的企业邮箱 | mail:user_mailbox:readonly | |
查询个人邮箱信息 | corehr:person.email:read | |
获取通讯录基本信息 | contact:contact.base:readonly | |
以应用身份读取通讯录 | contact:contact:readonly_as_app | |
获取与发送单聊、群组消息 | im:message | 使用飞书推送消息需要 |
以应用的身份发消息 | im:message:send_as_bot | 使用飞书推送消息需要 |
给一个或多个部门的成员批量发消息 | im:message:send_multi_depts | 使用飞书推送消息需要 |
给多个用户批量发消息 | im:message:send_multi_users | 使用飞书推送消息需要 |
获取与上传图片或文件资源 | im:resource | 使用飞书推送消息需要 |
可在飞书权限配置中搜索下面 code 快速开通需要的权限:
basic
contact:contact:readonly_as_app,contact:contact.base:readonly,admin:app.user_usable:readonly,contact:user.department:readonly,contact:user.email:readonly,contact:user.employee_id:readonly,contact:group:readonly,contact:user.id:readonly,contact:user.phone:readonly,contact:user.gender:readonly,contact:user.job_level:readonly,mail:user_mailbox:readonly,corehr:person.email:read,im:message,im:message:send_as_bot,im:message:send_multi_depts,im:message:send_multi_users,im:resource
1
版本管理与发布,创建版本,根据需要及飞书要求填写应用版本号,更新说明,选择可用范围。申请线上发布。
应用审核。 8.1 人工审核:进入飞书管理后台
https://bc0nlvsmah.feishu.cn/admin/appCenter/audit
, 选择需要审核的应用进行审核。 8.2 自动审核:进入飞书管理后台,应用管理,https://bc0nlvsmah.feishu.cn/admin/appCenter/manage
选择需要设置自动审核的应用,点击配置,打开免审功能。在系统中配置飞书自建应用的 App ID 和 App Secret.
飞书认证方式相关文档,可以参考:
- 应用免登
- 查看 App ID,App Secret 进入飞书开放平台,选择具体应用,查看 App ID 和 App Secret。
- 飞书管理后台
https://bc0nlvsmah.feishu.cn/admin/appCenter/manage
免登进入具体的应用 如果在凭证与基础信息的综合信息中,填写了管理后台主页地址,则可以在飞书管理后台免登进入应用。
请注意
飞书文档可能会有变动,以飞书官方文档为准。
通用配置
部分认证方式(如:OAuth2,jwt-param 等)支持登录名、邮箱、手机等的映射配置,在有这些配置项的认证方式下,这些配置具有同样的含义。
启用用户属性同步:配置是否同步用户属性。
用户名映射:客户系统中的某字段将做为系统中用户的登录名,要求全系统唯一,目的是每次登录可以自动关联到该用户。
显示名映射:客户系统中的某字段将做为系统中用户的显示名。
邮箱映射:客户系统中的某字段将做为系统中用户的邮箱,要求全系统唯一,目的是每次登录可以自动关联到该用户。
手机号映射:客户系统中的某字段将做为系统中用户的手机号,要求全系统唯一。
角色映射:客户系统中的某字段将做为系统中该用户所拥有的角色,可以传递角色 ID 或者角色标识,如不传递,则默认是数据查看者。角色标识和角色名称对应如下:
- system admin:系统管理员。
- data admin:数据管理员。
- data analyst:数据分析员。
- data viewer:数据查看员。
- api admin:api 管理员。
组映射:客户系统中的某字段将做为系统中该用户所属的组,可以传递用户组 ID 或者用户组名。
组织架构映射:可已将客户系统中的组织架构映射到衡石系统中。
企业 ID 映射:租户方式登录时该字段可用于映射系统中的企业 ID。
企业名称映射:租户方式登录时该字段可用于映射系统中的企业名称。
平台方 ID:该字段存放平台方 ID。
启用 SSO exp 会话有效期同步:是否同步会话中的有效期。
会话有效期映射:会话有效期字段,默认为 exp。
以 JSON 示例,如果客户系统中传递的 json 如下:
json
{
"uniqueName":"zhangsan", //唯一标识
"nickname":"张 san",
"name":"张三",
"given_name":"张三",
"family_name":"张",
"roles":[
"data admin", //角色标识
"data analyst"
],
"groups":[
"group1", //用户组名称
"group2"
],
"email":"zhangsan@hengshi.com"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在 HENGSHI 中的登录名映射应配置为 uniqueName 在 HENGSHI 中的用户名映射应配置为 name 在 HENGSHI 中的邮箱映射应配置为 email 在 HENGSHI 中的角色映射应配置为 roles 在 HENGSHI 中的用户组映射应配置为 groups
认证方式集成说明
- HENGSHI SENSE 系统支持多重认证方式,在不同的场景下,可以选择不同的认证方式。
- 无论选择那种认证方式,都可以通过 HENGSHI 用户名密码登录,登录地址为:http://{host}:{port}/login 。
- HENGSHI 认证方式的选择支持配置页面选择和 url 传参两种方式,在配置页面选择意味着是默认的认证方式,url 中没有 指定的时候,就会采用该认证方式进行认证,如果在 url 中指定了具体的认证方式,则优先使用 url 中的认证方式。比如: 认证方式配置选择的是 HENGSHI,但是在 url 中指定了 activeAuth=oauth2,则会使用 OAuth2 进行认证。 示例:
http://{host}:{port}/?activeAuth=oauth2#/
1
- 租户 url 传参指定认证方式需要传递 tenantCode={tenantCode},或者 tenantId={tenantId} 示例:
http://{host}:{port}/?activeAuth=oauth2&tenantCode={tenantCode}#/
1
浏览器中直接使用 HENGSHI 系统场景
用户在浏览器中使用 HENGSHI 系统,并且只有一种认证方式的场景下,只需配置相应的认证方式,并选择该认证方式即可。
iframe 嵌入 HENGSHI 页面的场景
用户可能会直接在浏览器使用 HENGSHI SENSE 系统进行应用创建,然后使用 iframe 将 HENGSHI 看图页面嵌入到客户的系统中,通过 SSO 实现免登 在该场景下,以 OAuth2 为例说明:
用户通过浏览器使用 HENGSHI SENSE 系统做图和 iframe 嵌入的看图都是通过用户的 OAuth Server 实现免登,那么只需要配置 OAuth 认证方式, reloadUser 设置为 false,iframe 的嵌入地址为 http://{host}:{port}/?reloadUser=true#/,reloadUser=true 的作用是用户在 在客户主站登出以后,切换用户后进入 HENGSHI 页面时,HENGSHI 会重新从 OAuth Server 获取当前登录的用户。在浏览器中使用 HENGSHI SENSE 系统做图, 并不会有主站登出的情况,所以并不需要每次都去 OAuth Server 获取当前登录的用户。
用户通过浏览器使用 HENGSHI SENSE 系统做图使用 HENGSHI SENSE 的用户名密码登录,iframe 使用 OAuth Server 实现免登。
2.1 认证方式选择 HENGSHI 认证,用户通过浏览器使用 HENGSHI SENSE 系统做图时使用该方式登录
2.2 需要配置 OAuth2 认证方式,reloadUser 设置为 false,iframe 的嵌入地址为
http://{host}:{port}/?activeAuth=oauth2&reloadUser=true#/,
用户看图时实现免登。
移动端微应用嵌入 HENGSHI 页面的场景
移动端主要支持了 钉钉,企业微信,云之家。 移动端微应用嵌入 HENGSHI 页面的使用方式和 iframe 嵌入 HENGSHI 页面的场景大体一致。 区别只是会在移动端微应用管理页面配置多个 HENGSHI 页面地址。以企业微信为例
- 选择 HENGSHI 认证,用户使用 HENGSHI 的用户名密码在网页登录,做图。
- 在企业微信自建应用管理页面配置 HENGSHI 的嵌入地址
http://{host}:{port}/?activeAuth=wechat-work&wcwLoginType=oauth2#/
, 在移动端或桌面端即可免登访问 HENGSHI。