技术文章

当前位置:首页>帮助手册>技术文章

使用鉴权配置控制接口的调用权限

时间:2022-08-01   
内容导读

本篇介绍在 O2OA 平台的服务管理平台中新建接口,并用地址表达式限定可调用来源的做法。文中说明以正则匹配客户端地址的写法,只有匹配通过时接口才会执行,适合按来源收紧权限的场景。开启鉴权后须同时传入客户端名称与加密票据,因此还要先准备鉴权配置,文中也给出了密钥配置的入口位置与调用地址的查看处,并附上多语言加密样例,便于外部系统对照接入。

本文介绍O2OA服务管理中,接口的权限设定和调用方式。
适用版本:5.4及以上版本

创建接口

具有服务管理设计权限的用户(具有 ServiceManager 角色或 Manager 角色)打开“服务管理平台”,进入接口配置视图,点击左上角的新建按钮即可创建接口。

image.png

请输入搜索关键字
服务管理
流星管理-合同
页
系统设
数层应用管理-智能物联
在设计中查找
数振中心兰理
济程应用兰理
huqi
接口配置
代理配痘
2T1Cm3rlEv
222
1ia4HLKweM
1111222
游
T1Cm3rlE
1ia4HLKweM
2020-12-1615:15:45
2020-11-1012:17:29
?
2021-01-2015:09:07
202012-1615:15:31
333333
CcHAn5NTGL
exil4NMPh3
getService
接口配智
CCHANSNtGL
exi4NMPh3
2020-11-1012:28:08
2020-12-1615:15:27
2020-11-1012:17:29
2020-12-1615:10:45
qVhE54pGRC
irstudysuccess
gzVsWx1Uk5
getToken
qVhFS4PGRC
gzVSWx1uk5
2020-11-1012:17:29
2021-01-1723:58:54
202012-1615:15:28
2020-12-1615:15:24
V2ZX1rOEZK
XGMDo82eUV
test1
report
XGMDo82eUV
V2ZX1rOEzK
2020-11-1012:17:29
2021-01-1301:15:12
2020-12-1615:15:55
202012-1615:10:41


新建接口后,在右侧属性栏中有两个配置和调用权限有关,一个是“允许访问的地址表达式”,一个收是“启用鉴权”。
属性
标识:
2fc68278-eea5-4145-813f-75f5506aa7d1
名称:
别名:
充许访问的地址表达式:
最近开始时间:
最近结束时间:
描述:
启用鉴权:
启用鉴权后,您必须使用鉴权客户端名称和加密后的token来调用服务
是否启用:
是
调用地址:
http://develop.o2oanet20030/xprogramcenter/axrs/invoke/2fc
68278-eea5-4145-813-75f55067d/client/clienttoken/toke
ny/execute
image.png

允许访问的地址表达式

此处可输入一个正则表达式,用于匹配调用接口的客户端 Remote_Addr,仅匹配通过时接口才允许执行。例如仅允许 172.16.1.50 到 172.16.1.56 的地址调用接口,可输入:

Plain Text复制代码

1

172.16.1.5[0-6]

启用鉴权

此处选择“是”的话,就需要在调用接口时传入client名称和一个加密后的token。所以我们先需要一组鉴权配置。
具有管理员权限的用户(具有Manager角色),打开“系统设置”-“安全配置”-“单点登录”,找到“鉴权密钥配置”。
请输入搜索美解字
I
服务包讯
蒸设面
流是应用具
数提应用理智时联
在设计中点饿
huqi
敬捐中心管理
流程管理.合同
云服务配置
移动办公配置
系统部薯
基础配置
界面配置
配置与其他系统的鉴权和单点登录设置
系统名称配
鉴权配嗜
系统用户配货
您可以个系统创主紧权,用于SSO正录和服务识用
系统节录配店
添加鉴权配居
自
系统SSO配
平台配三
OAUTH客户端配置
如果本系统作为OAUTH2以证服务器,您可以在此可以多个OAUTH密营,为其他统实现授权
添加oauth配盟
OAUTH服务端配置
如果本系统市通过其他OAUIH务需认证,您可以在此可以多OAUi务漓,为本系统实现设仪
添加oauth配查
企业微信配置
系统可以和企业微信供成,请先配店微信企业号和密钥
编转企业微信配三
corpld:
钉钉配置
您可以省年成违配省打价企业号和咬钜

image.png

点击“添加鉴权配置”:
添加鉴权配置
是否启用
务器,您可
yes
鉴权名称
密钥(最少8位)
12服务器认
确定
取消
配置微信企业号和密钥

image.png

此处需要配置一个名称和密钥。
名称:可随意填写,就是我们在调用接口或进行SSO时要传入的client参数。
密钥:可随意填写,用于后续加密,最少8位。

此处我们假设名称填写:oa;密钥填写:platform
填写完成后确定。
鉴权配置
您可以为多个系统创建鉴权,用于SSO登录和服务调用
添加鉴权配置
oa

image.png

接下来即可使用此鉴权配置调用接口。


接口调用

接口调用地址在接口属性栏中有显示:

描述:
启用鉴权:
是
启用鉴权后,您必须使用鉴权客户端名称和加密后的token来调用服务
是否启用:
是
调用地址:
htpj/developozoant2039progamcentt/x/oke/sapolenyemokokeee
调用方法:

image.png


启用鉴权后的接口调用地址为:

http://develop.o2oa.net:20030/x_program_center/jaxrs/invoke/{name}/client/{client}/token/{token}/execute
请求方法为:POST

地址中的{name}为接口的名称或别名;
地址中的{client}为鉴权的名称;
地址中的{token}为:用户名#1970年毫秒数 使用鉴权密钥经过3DES加密后的值。

javascript 加密代码样例

我们使用CryptoJS进行3DES加密。(GitHub:https://github.com/brix/crypto-js)
JavaScript复制代码



function crypDES (value, key) {

    var keyHex = CryptoJS.enc.Utf8.parse(key);

    var xtoken = CryptoJS.DES.encrypt(value, keyHex, {

      mode: CryptoJS.mode.ECB,

      padding: CryptoJS.pad.Pkcs7

    });

    var str = xtoken.ciphertext.toString(CryptoJS.enc.Base64);

    str = str.replace(/=/g, "");

    str = str.replace(/+/g, "-");

    str = str.replace(///g, "_");

    return str;

}


样例:
JavaScript复制代码

1

var login_uid = "test";
2

var time = new Date().getTime();
3

var sso_key = "12345678";
4

var xtoken = crypDES( login_uid + "#" + time, sso_key );

IOS 加密代码样例

Swift复制代码

1

/// o2oa 3DES加密 @param publicKey 加密公钥
2

func o2DESEncode(code: String, publicKey: String) -> String? {
3

    if let encode = desEncrypt(code: code, key: publicKey, iv: "12345678", options: (kCCOptionECBMode + kCCOptionPKCS7Padding)) {
4

        let first = encode.replacingOccurrences(of: "+", with: "-")
5

        let second = first.replacingOccurrences(of: "/", with: "_")
6

        let token = second.replacingOccurrences(of: "=", with: "")
7

        return token
8

    }else {
9

        print("加密错误")
10

        return nil
11

    }
12

}
13

/// 3DES 加密
14

func desEncrypt(code: String, key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
15

    if let keyData = key.data(using: String.Encoding.utf8),
16

        let data = code.data(using: String.Encoding.utf8),
17

        let cryptData    = NSMutableData(length: Int((data.count)) + kCCBlockSizeDES) {
18


19

        let keyLength              = size_t(kCCKeySizeDES)
20

        let operation: CCOperation = UInt32(kCCEncrypt)
21

        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmDES)
22

        let options:   CCOptions   = UInt32(options)
23


24

        var numBytesEncrypted :size_t = 0
25


26

        let cryptStatus = CCCrypt(operation,
27

                                  algoritm,
28

                                  options,
29

                                  (keyData as NSData).bytes, keyLength,
30

                                  iv,
31

                                  (data as NSData).bytes, data.count,
32

                                  cryptData.mutableBytes, cryptData.length,
33

                                  &numBytesEncrypted)
34


35

        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
36

            cryptData.length = Int(numBytesEncrypted)
37

            let base64cryptString = cryptData.base64EncodedString()
38

            return base64cryptString
39

        }
40

        else {
41

            return nil
42

        }
43

    }
44

    return nil
45

}
样例:
Swift复制代码

1

let uid = "test"
2

let timeInterval = Date().timeIntervalSince1970
3

let time = CLongLong(round(timeInterval*1000))
4

let code = "(uid)#(time)"
5

let xtoken = code.o2DESEncode() ?? ""

Android 加密代码样例

Kotlin复制代码

1

fun o2DESEncode(code: String, publicKey: String): String {
2

    val sutil = CryptDES.getInstance(publicKey)
3

    var encode = ""
4

    try {
5

        encode = sutil.encryptBase64(code)
6

        Log.d(LOG_TAG,"加密后code:$encode")
7

        encode = encode.replace("+", "-")
8

        encode = encode.replace("/", "_")
9

        encode = encode.replace("=", "")
10

        Log.d(LOG_TAG,"替换特殊字符后的code:$encode")
11

    }catch (e: Exception) {
12

        Log.e(LOG_TAG,"加密失败", e)
13

    }
14

    return encode
15

}
16


17

public class CryptDES {
18

    private Cipher encryptCipher = null;
19

    private Cipher decryptCipher = null;
20

    private static CryptDES des = null;
21

    public static CryptDES getInstance(String des_key) {
22

        try {
23

            DESKeySpec key = new DESKeySpec(des_key.getBytes());
24

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
25

            des = new CryptDES(keyFactory.generateSecret(key));
26

        } catch (Exception e) {
27

            e.printStackTrace();
28

        }
29

        return des;
30

    }
31

    private CryptDES(SecretKey key) throws Exception {
32

        encryptCipher = Cipher.getInstance("DES");
33

        decryptCipher = Cipher.getInstance("DES");
34

        encryptCipher.init(Cipher.ENCRYPT_MODE, key);
35

        decryptCipher.init(Cipher.DECRYPT_MODE, key);
36

    }
37

    public String encryptBase64 (String unencryptedString) throws Exception {
38

        // Encode the string into bytes using utf-8
39

        byte[] unencryptedByteArray = unencryptedString.getBytes("UTF8");
40

        // Encrypt
41

        byte[] encryptedBytes = encryptCipher.doFinal(unencryptedByteArray);
42

        // Encode bytes to base64 to get a string
43

        byte [] encodedBytes = Base64.encode(encryptedBytes, Base64.DEFAULT);
44

        return new String(encodedBytes);
45

    }
46

    public String decryptBase64 (String encryptedString) throws Exception {
47

        // Encode bytes to base64 to get a string
48

        byte [] decodedBytes = Base64.encode(encryptedString.getBytes(), Base64.DEFAULT);
49

        // Decrypt
50

        byte[] unencryptedByteArray = decryptCipher.doFinal(decodedBytes);
51

        // Decode using utf-8
52

        return new String(unencryptedByteArray, "UTF8");
53

    }
54

}

Java 加密代码样例

JavaScript复制代码

1

Crypto.java
2

import java.io.IOException;
3

import java.net.URLDecoder;
4

import java.net.URLEncoder;
5

import java.security.SecureRandom;
6

import javax.crypto.Cipher;
7

import javax.crypto.SecretKey;
8

import javax.crypto.SecretKeyFactory;
9

import javax.crypto.spec.DESKeySpec;
10

import org.apache.commons.codec.binary.Base64;
11

import org.apache.commons.lang3.StringUtils;
12

/**
13

 * encrypt and decrypt utils
14

 * @author O2OA
15

 *
16

 */
17

public class Crypto {
18

    private static final String utf8 = "UTF-8";
19

    private final static String DES = "DES";
20

    private final static String cipher_init = "DES";
21

    public static String encrypt(String data, String key) throws Exception {
22

      byte[] bt = encrypt(data.getBytes(), key.getBytes());
23

      String str = Base64.encodeBase64URLSafeString(bt);
24

      return URLEncoder.encode( str, utf8 );
25

  }
26

  public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
27

      // 生成一个可信任的随机数源
28

      SecureRandom sr = new SecureRandom();
29

      // 从原始密钥数据创建DESKeySpec对象
30

      DESKeySpec dks = new DESKeySpec(key);
31

      // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
32

      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
33

      SecretKey securekey = keyFactory.generateSecret(dks);
34

      // Cipher对象实际完成加密操作
35

      Cipher cipher = Cipher.getInstance(cipher_init);
36

      // 用密钥初始化Cipher对象
37

      cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
38

      return cipher.doFinal(data);
39

  }
40

  public static String decrypt(String data, String key) throws IOException, Exception {
41

      if (StringUtils.isEmpty(data)) {
42

          return null;
43

      }
44

      String str = URLDecoder.decode(data, utf8);
45

      byte[] buf = Base64.decodeBase64(str);
46

      byte[] bt = decrypt(buf, key.getBytes());
47

      return new String(bt);
48

  }
49

  public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
50

      // 生成一个可信任的随机数源
51

      SecureRandom sr = new SecureRandom();
52

      // 从原始密钥数据创建DESKeySpec对象
53

      DESKeySpec dks = new DESKeySpec(key);
54

      // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
55

      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
56

      SecretKey securekey = keyFactory.generateSecret(dks);
57

      // Cipher对象实际完成解密操作
58

      Cipher cipher = Cipher.getInstance(cipher_init);
59

      // 用密钥初始化Cipher对象
60

      cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
61

      return cipher.doFinal(data);
62

  }
63

}
调用:
Java复制代码

1

String login_uid = "test";
2

long time = new Date().getTime();
3

String sso_key = "12345678";
4

String xtoken = Crypto.encrypt( login_uid + "#" + time, sso_key );
5


用户常见问题

整理自藕粉社区真实提问,按浏览量排序

Q流程表单调用自定义接口的 Action 时提示跨域

具有服务管理设计权限的用户(具有 ServiceManager 角色或 Manager 角色)打开“服务管理平台”,进入接口配置视图,点击左上角的新建按钮,可创建一个新的接口。

查看原帖讨论 · 19,514 次浏览

以上问题仍无法解决?到 藕粉社区 提问,或致电 400-888-0545。

相关内容

O2OA 翱途 企业应用开发平台

兰德网络O2OA平台软件

开源、自主可控的协同办公底座

研发与运营

纵横翱途(杭州)科技有限公司

企业级协同应用 · 工作流引擎 · AI 智能体

www.o2oa.net | 400-888-0545

上一篇:导出o2server docker镜像文件实现在内网导入部署o2server docker镜像

下一篇:使用鉴权配置实现外部系统与O2OA 平台的单点登录