---
order: 3
---
# 连接OAuth2服务

\[\[toc]]

## OAuth2服务简介{#indroduction}

OAuth（开放授权）是一个开放标准，允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息，而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。[OAuth2协议](https://oauth.net/2/)是OAuth协议的延续版，在各互联网平台上有的广泛的应用。

SuccBI连接OAuth2服务，可以让用户第一次访问SuccBI内部资源时显示OAuth2服务器的登录页面（或者是授权页面），如果用户之前已经在当前浏览器窗口登录过，那么也可以直接静默授权，不显示登录/授权页面，直接自动登录SuccBI显示用户想看到的内容。

## 使用第三方OAuth2服务登录流程{#oauth-login-flow}

SuccBI内置有调用第三方OAuth2服务API来获取授权，这个需要第三方OAuth2服务满足下列流程：

![流程图](./images/oauth2-sso-sequence.png)

第三方OAuth2服务需要满足如下条件：

1. 提供三个api接口用于SuccBI来获取授权认证信息：

   - 获取用户授权接口(对应流程图第2步)：用于SuccBI在没有登录的时候跳转过来获取用户授权。
   - 根据给用户授权生成的授权码获取接口调用凭证（access\_token）（对应流程图第11步）：用于认证SuccBI身份。如果是需要`POST`请求，请确保可以解析以`JSON`格式传递的数据。
   - 根据接口调用凭证（access\_token）获取用户信息（对应流程图第14步）。如果是需要`POST`请求，请确保可以解析以`JSON`格式传递的数据。

2. 用户完成授权后重定向回SuccBI系统（对应流程图第9步）的url中带的用户授权凭证参数需要命名为**code**才会被SuccBI识别。

::: tip
如果第三方OAuth2服务不能满足如上条件，可以尝试使用[单点登录扩展服务](../../dev/extension/extension-points/sso.md)进行自定义。
:::

## 配置第三方OAuth2服务{#oauth2-service-settings}

在**系统设置** > **安全** > **单点登录** 中提供配置多个OAuth2服务的配置。[基本设置参考](../../sys-settings/security/sso.md)。

![单点登录系统设置入口](./images/syssettings-sso.png)
![oauth2特征设置1](./images/syssettings-sso-oauth2.png)

说明：

1. **appid**: 第三方OAuth2服务给SuccBI分配的id。`非必要选项`，可选择直接填写到对应URL参数中。用于认证身份。

2. **appsecret**：第三方OAuth2服务给SuccBI分配的秘钥。`非必要选项`，可选择直接填写到对应URL参数中。用于进一步认证身份。

3. **授权登录页面URL**：当SuccBI没有登录时候，跳转到的第三方OAuth2服务地址。`必要选项`。填入的URL中可使用的参数有：

   - ${state}：状态值。用于防止[CSRF攻击](https://zh.wikipedia.org/wiki/%E8%B7%A8%E7%AB%99%E8%AF%B7%E6%B1%82%E4%BC%AA%E9%80%A0)，最终将被替换为一个随机字符串。期望第三方OAuth2服务在完成认证后原样传递给SucccBI，如果第三方OAuth2服务没有实现该机制，可选值不传这个参数。
   - ${appid}：将被替换为系统设置中`appid`作为身份认证信息
   - ${redirect\_uri}：将被替换为登录成功后期望访问的SuccBI的URL地址，供第三方OAuth2服务在完成认证后重定向回SuccBI。

   示例： `http://example.com/authorize?appid=${appid}&redirect_uri=${redirect_uri}&state=${state}`\
   最终将在使用的时候后将会被替换为： `http://example.com/authorize?appid=succbiid&redirect_uri=http%3A%2F%2Fsuccbi.com&state=12345`

4. **读取access\_token的URL**：用于SuccBI向第三方OAuth2服务根据用户授权凭证换取接口调用凭证(access\_token)。`必要选项`。默认是使用`GET`请求来进行调用，如果需要使用`POST`请求来调用，可以使用`POST + 一个空格` 作为前缀来指定，其他参数根据URL的的参数规范放置到URL中。URL中可使用的参数变量有：

   - ${code}：第三方OAuth2服务在确认用户授权后重定向SuccBI所携带的授权信息。
   - ${appid}：将被替换为系统设置中`appid`作为身份认证信息。
   - ${app\_secret}：将被替换为系统设置中`appsecret`作为身份认证信息。
   - ${redirect\_uri}：将被替换为第三方系统确认用户授权后重定向到SuccBI的URL地址。

   示例：`POST http://example.com/access_token?appid=${appid}&appsecret=${app_secret}&redirect_uri=${redirect_uri}&code=${code}`\
   最终发送出去的请求为信息的http请求关键信息如下：

   ```json
   {
       Request URL: "http://example.com/access_token",
       Request Method: "POST",
       Content-Type: "application/json;charset=utf-8"
       Request Body: "{
           "appid": "succbi",
           "appsecret": "succbisecret",
           "code": "code",
           "redirect_uri": "http://succbi.com/demo"
       }"
   }
   ```

5. **解析access\_token**：用于告知SuccBI使用什么方式解析请求**读取access\_token的URL**的返回值。`必要选项`。为一个[表达式](../../exp/README.md)。\
   示例：`JSON_GET($response, "access_token")`
   - `$response`代表http请求的返回值的字符串结果。
   - 整体表达式代表的意思是，将响应值作为一个JSON字符串解析，并且取JSON中键为`access_token`的值作为`access_token`。

6. **注销URL**：用于在用户注销在SuccBI注销登录的时候通知第三方OAuth2服务。`非必要选项`。URL上可用的参数有：

   - ${appid}：将被替换为系统设置中`appid`作为身份认证信息。
   - ${app\_secret}：将被替换为系统设置中`appsecret`作为身份认证信息。
   - ${redirect\_uri}：注销SuccBI后期望重定向到的SuccBI的系统界面URL。
   - ${state}: 状态值。

   示例： `http://example.com/authorize?appid=${appid}&redirect_uri=${redirect_uri}&state=${state}`\
   最终将在使用的时候后将会被替换为： `http://example.com/authorize?appid=succbiid&redirect_uri=http%3A%2F%2Fsuccbi.com&state=12345`

7. **获取用户信息URL**：用于使用接口调用凭证(access\_token)向第三方OAuth2服务换取用户信息。`必要选项`。默认是使用`GET`请求来进行调用，如果需要使用`POST`请求来调用，可以使用`POST + 一个空格` 作为前缀来指定，其他参数根据URL的的参数规范放置到URL中：

   - ${access\_token}：接口调用凭证。
   - ${appid}：将被替换为系统设置中`appid`作为身份认证信息。

   示例：`POST http://example.com/access_token?access_token=${access_token}`\
   最终发送出去的请求为信息的http请求关键信息如下：

   ```json
   {
       Request URL: "http://example.com/getUser",
       Request Method: "POST",
       Content-Type: "application/json;charset=utf-8"
       Request Body: "{
           "access_token": "wz4e5x6rc7tv8yb9uni=-908778-980ytfufuyghoti7rdtyg",
       }"
   }
   ```

8. **解析用户信息**：用于控制如何从请求`获取用户信息URL`的响应中中获取用户信息。`非必要选项`。
   - 不填的情况下，如果返回值是JSON格式，则会取这个JSON中键名为`user`的对象作为完整的用户属性。\
     示例：

     ```json
        {
            user: {
                userId: "zhangsan",
                userName: "张三",
                enabled: true
            },
            errorcode: 0
        }
     ```

     将直接取 `user`的整个属性，作为用户数据。

   - 填写的情况下，需要针对需要写入到系统用户表字段，分别使用表达式进行解析，填写方式如下：
     - 左边为属性名，根据用户表字段来命名，不过得将下划线命名方式的用户表字段，修改为驼峰式命名，比如用户表字段为`USER_ID`，则需要填入`userId`。
     - 右边为取值表达式：

       - 表达式以`$response`作为http请求的返回值的字符串常量，比如`JSON_GET($response, 'userId')`，表明取JSON的第一级参数userId对应的值。
       - 也可以使用常量，如果是个字符串，需要用引号括起来，比如填入"external"，表明固定写入字符串`external`。

       示例：
       ![系统设置-解析用户信息](./images/syssettings-sso-oauth2-userinfo.png)

## 相关阅读{#related-texts}

- [SuccBI提供的OAuth2服务](../../dev/references/web-api/oauth2/README.md)
- [单点登录扩展服务](../../dev/extension/extension-points/sso.md)
- [OAuth标准(英文)](https://oauth.net/2/)
- [OAuth维基百科(中文)](https://zh.wikipedia.org/zh/%E5%BC%80%E6%94%BE%E6%8E%88%E6%9D%83)
